LINQ to XML 忽略属性中的换行符
Posted
技术标签:
【中文标题】LINQ to XML 忽略属性中的换行符【英文标题】:LINQ to XML ignores line breaks in attributes 【发布时间】:2012-07-13 02:17:02 【问题描述】:根据这个问题:
Are line breaks in XML attribute values allowed?
XML 属性中的换行符完全有效(尽管可能不推荐):
<xmltag1>
<xmltag2 attrib="line 1
line 2
line 3">
</xmltag2>
</xmltag1>
当我使用 LINQ to XML (System.Xml.Linq
) 解析此类 XML 时,这些换行符会静默转换为空格 ' '
字符。
有没有办法告诉XDocument.Load()
解析器保留这些换行符?
P.S.:我正在解析的XML是第三方软件写的,所以我无法改变换行符的写法。
【问题讨论】:
如果您以编程方式编写属性,请查看这篇文章,该文章显示了转义字符串的不同方式。weblogs.sqlteam.com/mladenp/archive/2008/10/21/… 请记住,不仅换行符必须被转义。 【参考方案1】:如果您希望保留属性值中的换行符,那么您需要使用字符引用来编写它们,例如
<foo bar="Line 1. Line 2. Line3."/>
根据 XML 规范 http://www.w3.org/TR/xml/#AVNormalize,XML 解析器会将它们规范化为空格。
[编辑] 如果您想避免属性值规范化,那么使用旧版 XmlTextReader
加载 XML 会有所帮助:
string testXml = @"<foo bar=""Line 1.
Line 2.
Line 3.""/>";
XDocument test;
using (XmlTextReader xtr = new XmlTextReader(new StringReader(testXml)))
xtr.Normalization = false;
test = XDocument.Load(xtr);
Console.WriteLine("|0|", test.Root.Attribute("bar").Value);
输出
|Line 1.
Line 2.
Line 3.|
【讨论】:
谢谢,但正如我在问题中所写,XML 是由第三方软件编写的,所以我无法更改。也许我需要某种正则表达式替换,它将换行符转换为 我在您的问题中看到了该注释,但在这种情况下,有一个明确的规范,您得到的结果符合规范。所以我写了那个答案来指出你得到的行为是正确的,即使你的情况不需要。我认为旧版XmlTextReader
将允许您避免属性值规范化,因此我将编辑我的答案以显示这一点。【参考方案2】:
根据MSDN:
虽然 XML 处理器保留元素内容中的所有空白,但它们经常在属性值中对其进行规范化。制表符、回车和空格报告为单个空格。在某些类型的属性中,它们会修剪值主体之前或之后的空白,并将值中的空白减少为单个空格。 (如果 DTD 可用,将对所有非 CDATA 类型的属性执行此修剪。)
例如,一个 XML 文档可能包含以下内容:
<whiteSpaceLoss note1="this is a note." note2="this is a note.">
XML 解析器将两个属性值报告为
"this is a note."
,将换行符转换为单个空格。
我找不到任何关于保留属性空格的信息,但我想根据这个解释可能是不可能的。
【讨论】:
【参考方案3】:解析时换行符不是空格(不是 ASCII 代码 32)如果您逐步浏览每个字母,您会看到“空格 ' '”是 ASCII 代码 10 =LF(LineFeed)(!!) - 所以换行符仍然存在 如果您需要尝试在代码中用 ASCII 13 替换它们...(文本框(Windows 窗体)不将 LF 显示为换行符)
【讨论】:
谢谢,我之前测试过,我确实得到了两个 ASCII 码 32 个字符的换行符。为了确定,我将再次对其进行测试。 我又测试了一遍。 XML 属性中的'\r'
和'\n'
字符都转换为' '
空格(ASCII 代码32)。
你是对的 - 适用于 cdata 部分 - 目前找不到保留换行符的方法。将 32 32 替换为 LB 是否适合您?以上是关于LINQ to XML 忽略属性中的换行符的主要内容,如果未能解决你的问题,请参考以下文章
杰克逊:忽略空@XmlWrapperElement 集合中的空格