Кодування в XML (движок msxml)

Нічого не розумію. Створюю:

FEngine := CreateOLEObject("MSXML2.DOMDocument") as IXMLDOMDocument; FEngine.Async := false ;

if FEngine.parseError.errorCode <> 0 then raise Exception.Create(FEngine.parseError.reason);

Коли зчитую значення ноди Val:

TextNode := selectSingleNode("text()") as IXMLDOMText ; ShowMessage(TextNode.data);

Отримуємо кодування Windows-1251.

А якщо xml такий:

то отримуємо абракадабру. Таке відчуття, що msxml взагалі ігнорує вказівку кодування в XML-файлі. Чому він коректно не перетворює будь-яке вказане кодування до свого WideString (utf-16), звідки я вже читав би завжди також коректно?

І що робити в цій ситуації, адже я хочу вміти обробляти як XML з windows-1251, так і з utf-8.

> то отримуємо абракадабругм. garbage in, garbage out? відкрий свою иксемельку чимось крім своєї проги і перевір, сміття там чи потрібний рядок.

> Таке відчуття, що msxml взагалі ігнорує вказівку кодування > у xml-файлі

> гм. garbage in, garbage out? відкрий свою іксемільку чим- > то крім своєї проги і перевір, сміття там чи потрібний рядок.все ок там із кодуванням.

Але я помітив жахливу дивина. Якщо зберегти текст у файл і завантажити файл методом load, все дуже чудово.

А ось якщо як я написав вище – динамічно за допомогою методу loadXML – то з кодуванням проблеми. Що за річ. Тепер відчуття, що msxml плює на вказівку кодування при ДИНАМІЧНОМУ завантаженні xml'я.

до кодувань, з якими працює MSXML і до того, що внутрішнє уявлення в нього Unicode.

Ігоре Шевченко, ну а що толку, якщо при вказівці кодування: utf-8 в заголовку XML приДИНАМІЧНОМУ завантаженні - двигун не перетворює його на правильний формат?

Точніше, як я розумію, при динамічному завантаженні XML двигун просто плює на вказівку кодування і вважає її windows-1251 (що взагалі розходиться зі стандартом, за яким дефолтне кодування XML це utf-8). І відповідним чином перетворює на unicode, але оскільки припущення про початкове кодування неправильне - отримуємо фігню.

Питання - що робити млинець.

> Точніше, як я розумію, за динамічного завантаження XML двигун > просто плює на вказівку кодування та вважає її windows- > 1251

loadXML() метод буде працювати тільки з UTF-16 або UCS-2 encodings

Давно вже пора забути про Windows-1251. А то можна буде 866-кодову сторінку приплести. Або того гірше за КОІ-7. Це все минуле століття.

> loadXML() метод буде працювати тільки з UTF-16 або UCS-2 > encodingsопа, дійсно. Млинець дурість яка. Цікаво, чим обґрунтовано.

Справа в тому, що XML я отримую по мережі, мені б його зручно розпарсувати за допомогою msxml, а тут така підстава.

А є інший валідний спосіб, крім записувати щоразу XML у темпову директорію і нацьковувати вже на нього двигун msxml? (

> А є інший валідний спосіб, крім записувати кожен . раз XML у темпову директорію та нацьковувати вже на нього > двигун msxml? (

Якщо у нього відоме кодування UTF-8, то перетворювати на UTF-16 стандартним викликом Utf8ToUnicode, наприклад

> > Якщо у нього відоме кодування UTF-8так у тому й річ, що хочеться універсалізації та стандартизації.

Щоб не важливо, як відповідав віддалений сервіс, а парсилося завжди правильно. За фактом зараз буває чиutf-8, або windows-1251. Причому хочеться стандартизації за правилами XML, тобто якщо кодування не вказане - значить, воно дефолтне utf-8. Знову MS винайшли свій велосипед млинець.

Звичайно, можна милиці прилаштовувати, щоб самому відокремлювати тег кодування, далі перетворювати код XML і вже потім згодовувати його движку msxml, але даний варіант мене теж чомусь не тішить.

завантажуй із потоку (IStream), а не через loadXml(), тоді кодування буде враховуватися.

procedure TForm1.Button1Click(Sender: TObject); const s=" "+ " "+ " Рядок "+ " "; var FEngine:variant; begin FEngine := CreateOLEObject("MSXML2.DOMDocument") as IDispatch; FEngine.Async := false ; FEngine.load(TStreamAdapter.Create(TStringStream.Create(s),soOwned) as IStream); if FEngine.parseError.errorCode <> 0 then raise Exception.Create( FEngine.parseError.reason ); end;

> Знову MS винайшли свій велосипед млинець.Знову MS винен млинець. Користувався б не MSXML2.DOMDocument, а якимось іншим об'єктом, якщо ти думаєш, що там буде краще млинець.

Кодування в пролозі впливає на серіалізований документ. Поки цього немає, з кодуванням в пролозі можна взагалі не морочитися. Що у вузол записали, то і вважали

var xdoc ,xdoc1: IXMLDOMDocument2; begin xdoc := CoDOMDocument.Create; xdoc1 := CoDOMDocument.Create; xdoc.loadXML(" "); ShowMessage(xdoc.xml);//кодування вказане в пролозі зникло xdoc1.loadXML(xdoc.xml); // тим не менше воно працює ShowMessage (xdoc1.xml);

якщо xdoc зберегти у файл, кодування в пролозі з'явиться. Але якщо зберегти файл просто xdoc.xml.текст , то файл не завантажиться.

Або краще навіть так:

ShowMessage(xdoc.xml);//кодування вказане впролозі зникла

> Справа в тому, що XML я отримую по мережі, мені б його зручно розпарсувати за допомогою msxml, а тут така підстава. > А є інший валідний спосіб, крім записувати щоразу XML у темпову директорію і нацьковувати вже на нього двигун msxml? ( просто load(. ) із зазначенням url "з мережі"?)

Slym, супер, зашибісь. Дякую