给定此代码(C,.NET 3.5 SP1):

var doc = new XmlDocument();
doc.LoadXml("<?xml version=\"1.0\"?><root>"
    + "<value xml:space=\"preserve\">"
    + "<item>content</item>"
    + "<item>content</item>"
    + "</value></root>");

var text = new StringWriter();
var settings = new XmlWriterSettings() { Indent = true, CloseOutput = true };
using (var writer = XmlWriter.Create(text, settings))
{
    doc.DocumentElement.WriteTo(writer);
}

var xml = text.GetStringBuilder().ToString();
Assert.AreEqual("<?xml version=\"1.0\" encoding=\"utf-16\"?>\r\n<root>\r\n"
    + "  <value xml:space=\"preserve\"><item>content</item>"
    + "<item>content</item></value>\r\n</root>", xml);

断言失败,因为XmlWriter<item>元素周围插入新行和缩进,这似乎与xml:space="preserve"属性相矛盾。
我试图接受没有空白的输入(或者只有显著的空白,并且已经加载到XmlDocument中),并在没有在标记为保留空白的元素中添加任何空白的情况下(出于明显的原因)漂亮地打印它。
这是虫子还是我做错了什么?有没有更好的方法来实现我的目标?
编辑:我应该补充一下,我确实需要在输出端使用XmlWriterIndent=true。在“真实”代码中,这是从我的代码外部传入的。

最佳答案

好吧,我找到了一个解决办法。
结果是,如果XmlWriter块中确实有空白,那么xml:space="preserve"就做了正确的事情——只有在没有空白的情况下,它才会出错并添加一些空白。而且方便的是,如果有一些空白节点,即使它们是空的,也可以这样做。所以我想出的诀窍是在写出来之前,在适当的地方用额外的0长度的空白来修饰文档。结果正是我想要的:除了空格很重要的地方,到处都可以打印。
解决方法是将内部块更改为:

PreserveWhitespace(doc.DocumentElement);
doc.DocumentElement.WriteTo(writer);


private static void PreserveWhitespace(XmlElement root)
{
    var nsmgr = new XmlNamespaceManager(root.OwnerDocument.NameTable);
    foreach (var element in root.SelectNodes("//*[@xml:space='preserve']", nsmgr)
        .OfType<XmlElement>())
    {
        if (element.HasChildNodes && !(element.FirstChild is XmlSignificantWhitespace))
        {
            var whitespace = element.OwnerDocument.CreateSignificantWhitespace("");
            element.InsertBefore(whitespace, element.FirstChild);
        }
    }
}

不过,我仍然认为XmlWriter的这种行为是一个错误。

关于c# - XmlWriter在xml:space = preserve时插入空格,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7007533/

10-12 02:08