System.Xml 解析功能给我带来了一些惊喜,我想知道以下内容如何should被解释,或者如果这是“取决于实现”:
版本1:
<root><elem>
<![CDATA[MyValue]]>
</elem></root>
版本2:
<root><elem>
-<![CDATA[MyValue]]>-
</elem></root>
What should是 的值elem
?或者这取决于解析它的实现,我应该处理这个问题吗?
我期望(首先)在这两种情况下,开始/结束节点和第一个非空白字符之间的所有空白都将被忽略。事实并非如此,但如果不是这样,我至少会期望它never被忽略,但事实也并非如此。请参阅下面的完整重现以了解我的期望。
详细说明...
当我测试它们时,有两个案例让我难住了:
-
XDocument.Parse
会突然开始包括\n\t
示例 2 中的空格,而示例 1 中的空格则被忽略。
-
XDocument.Load
with 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"));
}
}