Как сделать так, чтобы TXMLDocument (с реализацией MSXML) всегда включал атрибут кодирования?

У меня есть устаревший код (я его не писал), который всегда включал атрибут кодирования, но перекомпилировав его в D2010, TXMLDocument больше не включает кодировку. Поскольку XML-данные имеют диакритические знаки как в тегах, так и в данных, TXMLDocument.LoadFromFile просто выдает EDOMParseErros, сообщая, что в файле обнаружен недопустимый символ. Соответствующий код:

   Doc := TXMLDocument.Create(nil);  
   try
     Doc.Active := True;
     Doc.Encoding := XMLEncoding;
     RootNode := Doc.CreateElement('Test', '');
     Doc.DocumentElement := RootNode;
     <snip>
     //Result := Doc.XMl.Text;
     Doc.SaveToXML(Result);    // Both lines gives the same result

В старых версиях Delphi генерируется следующая строка:

<?xml version="1.0" encoding="ISO-8859-1"?>

На D2010 это генерируется:

<?xml version="1.0"?>

Если я вручную меняю строку, все работает, как всегда работало в последние годы.

ОБНОВЛЕНИЕ: XMLEncoding является константой и определяется следующим образом

  XMLEncoding = 'ISO-8859-1';

person Fabricio Araujo    schedule 03.05.2010    source источник


Ответы (2)


Вы захотите увидеть IXMLDocument.CreateProcessingStruction. Я использую OmniXML, но его синтаксис аналогичен и должен помочь вам начать работу:

var
  FDoc: IXMLDocument;
  PI:  IXMLProcessingInstruction;
begin
  FDoc := OmniXML.CreateXMLDoc();
  PI := FDoc.CreateProcessingInstruction('xml', 'version="1.0" encoding="UTF-8"');
  FDoc.AppendChild(PI);
end;
person Ken White    schedule 03.05.2010
comment
Это именно то, что Microsoft рекомендует и для MSXML: msdn.microsoft.com/en- нас/библиотека/aa468560.aspx. Однако то, что стоит в начале документа, технически не является инструкцией по обработке. Это объявление XML; строка xml на самом деле не разрешена для имени инструкции обработки, поэтому кажется, что метод CreateProcessingInstruction выполняет двойную функцию. - person Rob Kennedy; 04.05.2010
comment
@Rob: Вероятно, поэтому пару лет назад мне потребовалось некоторое время, чтобы понять это (в то время у меня не было ссылки MSDN, которую вы предоставили). Однако на самом деле это можно считать инструкцией по обработке, не так ли, если она сообщает синтаксическому анализатору, как интерпретировать содержимое? Это XML, и он в этом наборе символов - так его будет легче понять. - person Ken White; 04.05.2010

var 
  XMLStream: TStringStream;
begin  
   Doc := TXMLDocument.Create(nil);  
   try
     Doc.Active := True;
     Doc.Encoding := XMLEncoding;
     RootNode := Doc.CreateElement('Test', '');
     Doc.DocumentElement := RootNode;
     <snip>
     XMLStream := TStringStream.Create;
     Doc.SaveToStream(XMLStream);
     Result := XmlStream.DataString;
     XMLStream.Free;

После ответа Кена и ссылки на статью MSXML я решил исследовать свойство XML и метод SaveToXML. Оба используют свойство XML реализации MSXMLDOM, о котором в статье говорится, что оно не приводит к кодировке при непосредственном чтении (в разделе «Создание новых XML-документов с помощью MSXML» сразу после использования метода CreateProcessInstruction).

ОБНОВИТЬ:

Я обнаружил, что символы с диакритическими знаками усекаются в результирующем XML. Когда процессор этого XML начал выдавать странные ошибки, мы увидели, что символы преобразуются в числовую константу char (#13 — числовая константа char для возврата каретки). Итак, я использовал TStringStream, чтобы сделать это НАКОНЕЦ правильным.

person Fabricio Araujo    schedule 04.05.2010