.NET XmlDocument: почему DOCTYPE изменяется после сохранения?

Я открываю файл XML с помощью .NET XmlReader и сохраняю файл под другим именем, и кажется, что объявление DOCTYPE меняется между двумя файлами. Хотя недавно сохраненный файл все еще является допустимым XML, мне было интересно, почему он настаивал на изменении исходных тегов.

Dim oXmlSettings As Xml.XmlReaderSettings = New Xml.XmlReaderSettings()
oXmlSettings.XmlResolver = Nothing
oXmlSettings.CheckCharacters = False
oXmlSettings.ProhibitDtd = False
oXmlSettings.IgnoreWhitespace = True

Dim oXmlDoc As XmlReader = XmlReader.Create(pathToOriginalXml, oXmlSettings)
Dim oDoc As XmlDocument = New XmlDocument()
oDoc.Load(oXmlDoc)
oDoc.Save(pathToNewXml)

Далее (в исходном документе):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">

становится (обратите внимание на символы [ ] в конце):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd"[]>

person Vincent    schedule 12.11.2008    source источник


Ответы (3)


Вероятно, библиотека анализирует элемент DOCTYPE во внутреннюю структуру, а затем преобразует структуру обратно в текст. Он не хранит исходную форму строки.

person David Norman    schedule 13.11.2008

В System.Xml есть ошибка, когда вы устанавливаете XmlDocument.XmlResolver = null. Обходной путь — создать собственный XmlTextWriter:

    private class NullSubsetXmlTextWriter : XmlTextWriter
    {
        public NullSubsetXmlTextWriter(String inputFileName, Encoding encoding)
            : base(inputFileName, encoding)
        {
        }
        public override void WriteDocType(string name, string pubid, string sysid, string subset)
        {
            if (subset == String.Empty)
            {
                subset = null;
            }
            base.WriteDocType(name, pubid, sysid, subset);
        }
    }

В своем коде создайте новый NullSubsetXmlTextWriter(pathToNewXml, Encoding.UTF8) и передайте этот объект методу oDoc.Save().

Вот обращение в службу поддержки Microsoft, где вы можете прочитать об обходном пути (он описывает обходной путь, но не предоставляет код).

person Maurice Flanagan    schedule 01.07.2009
comment
+1, потому что это работает. Однако это привело к тому, что мой HTML/XML был отформатирован странным, трудным для чтения способом. Для другого варианта этот ответ работал без вмешательства в формат документа: stackoverflow.com/a/16451790/279516. - person Bob Horn; 08.08.2016

Это лучшее решение для вас:

writer.WriteDocType("Name", Nothing, 
                    "http://xml.cxml.org/schemas/cXML/1.2.033/Fulfill.dtd", Nothing) 

Если вы используете Nothing, вы не получите [] или "" и т. д.

person parvez    schedule 24.10.2019