C#垃圾字符破坏XElement的“漂亮”表示

时间:2019-01-03 22:26:50

标签: c# xml xelement

我偶尔会在XML上碰到一些垃圾字符,这些垃圾字符被插入到元素之间,这似乎使内部XNode / XElement方法处理美化元素的做法感到困惑。

以下...

var badNode = XElement.Parse(@"<b>+
  <inner1/>
  <inner2/>
</b>"

打印出

<b>+
  <inner1 /><inner2 /></b>

与此同时...

var badNode = XElement.Parse(@"<b>
  <inner1/>
  <inner2/>
</b>"

给予期望

<b>
  <inner1 />
  <inner2 />
</b>

根据调试器,将垃圾字符解析为XElement的“ NextNode”属性,然后该属性显然将剩余的XML分配为其“ ”“ NextNode”,从而使单行更具美感。

是否有任何方法可以防止/忽略此行为,而无需为标记标记之间的任何错误字符预先筛选XML?

1 个答案:

答案 0 :(得分:1)

您会得到badNode的缩进,因为通过将非空格+字符添加到<b>元素值中,该元素现在包含mixed content,该字符已定义由W3C进行如下操作:

  

3.2.2混合内容

     

[定义:当某类型的元素可能包含字符数据(可选地散有子元素)时,该元素类型具有混合的内容。]

元素中存在混合内容会触发XmlWriter的特殊格式设置规则(XElement.ToString()在内部使用该规则将其实际写入XML字符串),{{3}中对此进行了解释}:

  

此属性仅适用于输出文本内容的documentation remarks for XmlWriterSettings.Indent实例;否则,将忽略此设置。

     

只要元素不包含混合内容,它们就会缩进。一旦调用WriteString或WriteWhitespace方法写出混合元素内容, XmlWriter便停止缩进。一旦混合内容元素关闭,缩进将恢复。

这说明了您所看到的行为。

作为一种解决方法,您可能需要使用XmlWriterparsing来{{3>}保留XML,而在解析时保留无关紧要的空白。

var badNode = XElement.Parse(@"<b>+
  <inner1/>
  <inner2/>
</b>",          
                             LoadOptions.PreserveWhitespace);
Console.WriteLine(badNode);

哪个输出:

<b>+
  <inner1 />
  <inner2 />
</b>

演示小提琴#1 LoadOptions.PreserveWhitespace

或者,如果您确定badNode不应包含字符数据,则可以在解析后手动剥离它:

badNode.Nodes().OfType<XText>().Remove();

现在badNode将不再包含混合内容,而XmlWriter将使其缩进。

演示小提琴#2 here