2015-11-15 5 views
0

XmlDocument добавляет пробел в конце закрывающих тегов, даже с PreserveWhitespace, установленным на true.XmlDocument не сохраняет пробелы

// This fails 
string originalXml = "<sample><node id=\"99\"/></sample>"; 

// Convert to XML 
XmlDocument doc = new XmlDocument(); 
doc.PreserveWhitespace = true; 
doc.LoadXml(originalXml); 

// Save back to a string 
string extractedXml = null; 

using (MemoryStream stream = new MemoryStream()) 
{ 
    doc.Save(stream); 

    stream.Position = 0; 
    using(StreamReader reader = new StreamReader(stream)) 
    { 
     extractedXml = reader.ReadToEnd(); 
    } 
} 

// Confirm that they are identical 
Assert.AreEqual(originalXml, extractedXml); 

Нужный выход:

<sample><node id="99"/></sample> 

Но я получаю:

<sample><node id="99" /></sample> 

Есть ли способ, чтобы подавить это дополнительное пространство?

+5

Просто из любопытства, почему это имеет значение? Документ структурно одинаковый в любом случае. –

+1

.Save использует XmlTextWriter внутренне и что дополнительное пространство документировано. –

+2

Вы можете использовать [XNode.DeepEquals] (https://msdn.microsoft.com/en-us/library/bb336169%28v=vs.110%29. aspx) для сравнения XML. Также см. Статью [this] (http://blogs.msdn.com/b/ericwhite/archive/2009/01/28/equality-semantics-of-linq-to-xml-trees.aspx). –

ответ

1

Вот как XmlDocument.Save(Stream) выглядит следующим образом:

public virtual void Save(Stream outStream) 
{ 
    XmlDOMTextWriter xmlDomTextWriter = new XmlDOMTextWriter(outStream, this.TextEncoding); 
    if (!this.preserveWhitespace) 
    xmlDomTextWriter.Formatting = Formatting.Indented; 
    this.WriteTo((XmlWriter) xmlDomTextWriter); 
    xmlDomTextWriter.Flush(); 
} 

Так установка PreserveWhiteSpace не оказывает никакого влияния на внутренней стороне узлов. documentation из XmlTextWriter говорит:

При написании пустого элемента, дополнительное пространство добавляется между именем тега и закрывающим тегом, например. Это обеспечивает совместимость со старыми браузерами.

Итак, я думаю, что нет простого выхода. Here «s обходной путь Тх:

Так что я написал класс обертки MtxXmlWriter, который является производной от XmlWriter и оборачивает оригинальный XmlWriter возвращенного XmlWriter.Create() и делает все необходимые трюки.

Вместо использования XmlWriter.Create() вы просто вызываете один из методов MtxXmlWriter.Create(), вот и все. Все другие методы напрямую передаются инкапсулированному оригинальному XmlWriter, за исключением WriteEndElement(). После вызова WriteEndElement() инкапсулированного XmlWriter «/>» заменяется на «/>» в буфере: