给定以下代码(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
)并漂亮地打印它without在标记为保留空格的元素内添加任何空格(出于明显的原因)。
这是一个错误还是我做错了什么?有没有更好的方法来实现我想要做的事情?
Edit:我可能应该补充一点,我确实必须使用XmlWriter
with Indent=true
在输出侧。在“真实”代码中,这是从我的代码外部传入的。
好的,我找到了解决方法。
事实证明XmlWriter
如果确实存在的话,就会做正确的事情is中的任何空格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
不过,这是一个错误。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)