C# XmlWriter在xml:space=preserve时插入空格
给出以下代码(C#,.NET 3.5 SP1):C# XmlWriter在xml:space=preserve时插入空格,c#,.net,xml,whitespace,xmlwriter,C#,.net,Xml,Whitespace,Xmlwriter,给出以下代码(C#,.NET 3.5 SP1): var doc=new XmlDocument(); doc.LoadXml(“”) + "" +“内容” +“内容” + ""); var text=新的StringWriter(); var settings=newxmlwritersettings(){Indent=true,CloseOutput=true}; 使用(var writer=XmlWriter.Create(文本、设置)) { doc.DocumentElement.Wri
var doc=new XmlDocument();
doc.LoadXml(“”)
+ ""
+“内容”
+“内容”
+ "");
var text=新的StringWriter();
var settings=newxmlwritersettings(){Indent=true,CloseOutput=true};
使用(var writer=XmlWriter.Create(文本、设置))
{
doc.DocumentElement.WriteTo(writer);
}
var xml=text.GetStringBuilder().ToString();
Assert.AreEqual(“\r\n\r\n”
+“内容”
+“内容\r\n”,xml);
断言失败,因为XmlWriter
正在
元素周围插入新行和缩进,这似乎与xml:space=“preserve”
属性相矛盾
我试图在输入时不带空格(或者只带重要空格,并且已经加载到XmlDocument
)并将其漂亮地打印出来,而不在标记为保留空格的元素中添加任何空格(出于明显的原因)
这是一个错误还是我做错了什么?有没有更好的方法来实现我的目标
Edit:我应该补充一点,我确实需要在输出端使用
XmlWriter
和Indent=true
。在“真实”代码中,这是从代码外部传入的。好的,我找到了一个解决方法
如果xml:space=“preserve”
块中实际上有任何空格,那么XmlWriter
做的事情是正确的——只有在没有空格的情况下才会出错并添加一些空格。方便的是,如果有一些空白节点,即使它们是空的,也可以这样做。所以我想出了一个技巧,在写文档之前,在适当的地方用额外的0长度空白来装饰文档。结果正是我想要的:除了空白很重要的地方,到处都可以打印
解决方法是将内部块更改为:
PreserveWhitespace(doc.DocumentElement);
doc.DocumentElement.WriteTo(writer);
private静态空格(xmlementroot)
{
var nsmgr=newxmlnamespacemanager(root.OwnerDocument.NameTable);
foreach(root.SelectNodes(“//*[@xml:space='preserve']”中的var元素,nsmgr)
.OfType())
{
if(element.HasChildNodes&&!(element.FirstChild是xmlsignantwhitespace))
{
var whitespace=element.OwnerDocument.createsignifictwhitespace(“”);
元素.InsertBefore(空白,元素.FirstChild);
}
}
}
不过,我仍然认为XmlWriter
的这种行为是一个bug
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);
}
}
}