System.Xml解析功能在我的商店中有一些惊喜,我想知道如何解释以下 ,或者如果这是"直到实现" :
版本1 :
<root><elem>
<![CDATA[MyValue]]>
</elem></root>
版本2:
<root><elem>
-<![CDATA[MyValue]]>-
</elem></root>
应该是elem
的值还是可以这取决于解析它的实现,我应该只处理它?
我预计(首先)在两种情况下,开始/结束节点和第一个非空白字符之间的所有空格都将被忽略。事实并非如此,但如果不这样做,我至少会期望从不被忽略,但事实并非如此。请参阅下面的完整repro以了解我的期望。
详细说明......
我测试时有两个案例让我难过:
XDocument.Parse
将突然开始在示例2中包含\n\t
空格,而在示例1中忽略它。XDocument.Load
与new XmlReaderSettings {IgnoreWhitespace = true}
的行为相似。是什么给出的?这只是实现(根据我的口味)古怪,和/或这是指定的行为吗?
这里完全符合我的期望(来自NuGet的最新NUnit软件包的新C#类库项目):
[TestFixture]
public class XmlTests
{
public static XDocument ParseDocument(string input)
{
return XDocument.Parse(input);
}
public static XDocument LoadDocument(Stream stream)
{
var xmlReader = XmlReader.Create(stream, new XmlReaderSettings() { IgnoreWhitespace = false }); // Default
return XDocument.Load(xmlReader);
}
public static XDocument LoadDocument_IgnoreWhitespace(Stream stream)
{
var xmlReader = XmlReader.Create(stream, new XmlReaderSettings() { IgnoreWhitespace = true });
return XDocument.Load(xmlReader);
}
const string example1 = "<root><elem>\n\t<![CDATA[MyValue]]>\n</elem></root>";
const string example2 = "<root><elem>\n\t-<![CDATA[MyValue]]>-\n</elem></root>";
[Test]
public void A_Parsing_Example1_WorksAsExpected()
{
var doc = ParseDocument(example1);
var element = doc.Descendants("elem").Single();
Assert.That(element.Value, Is.EqualTo("MyValue"));
}
[Test]
public void B_Loading_Example1_WorksAsExpected()
{
var doc = LoadDocument(new MemoryStream(Encoding.UTF8.GetBytes(example1)));
var element = doc.Descendants("elem").Single();
Assert.That(element.Value, Is.EqualTo("\n\tMyValue\n"));
}
[Test]
public void C_LoadingWithIgnoreWhitespace_Example1_WorksAsExpected()
{
var doc = LoadDocument_IgnoreWhitespace(new MemoryStream(Encoding.UTF8.GetBytes(example1)));
var element = doc.Descendants("elem").Single();
Assert.That(element.Value, Is.EqualTo("MyValue"));
}
[Test]
public void D_Parsing_Example2_WorksAsExpected()
{
var doc = ParseDocument(example2);
var element = doc.Descendants("elem").Single();
Assert.That(element.Value, Is.EqualTo("-MyValue-"));
}
[Test]
public void E_Loading_Example2_WorksAsExpected()
{
var doc = LoadDocument(new MemoryStream(Encoding.UTF8.GetBytes(example2)));
var element = doc.Descendants("elem").Single();
Assert.That(element.Value, Is.EqualTo("\n\t-MyValue-\n"));
}
[Test]
public void F_LoadingWithIgnoreWhitespace_Example2_WorksAsExpected()
{
var doc = LoadDocument_IgnoreWhitespace(new MemoryStream(Encoding.UTF8.GetBytes(example2)));
var element = doc.Descendants("elem").Single();
Assert.That(element.Value, Is.EqualTo("MyValue"));
}
}
答案 0 :(得分:2)
CDATAs很难。它们不会被解析器更改(读取)。不允许他们包含无效字符或]]>
。但是,某些实现会更改它们以生成有效的XML输出(写入)。
elem
的内容取决于解析器,是否忽略空白节点。 elem
有3个子节点。
\n\t
&#34; MyValue
&#34; \n
&#34; 所以就像你注意到如果忽略空白节点,只剩下cdata。在第二个例子中,结果会有所不同(如果已修复)。
\n\t-
&#34; MyValue
&#34; -\n
&#34; 第一个和第三个节点现在有非空白内容( - )。它们不再是空白节点,根据选项不会被忽略。