gpt4 book ai didi

c# - XmlDocument:空白处理和规范化

转载 作者:太空宇宙 更新时间:2023-11-03 21:18:09 26 4
gpt4 key购买 nike

我有一堆与 XmlDocument 的空格处理相关的问题.请参阅下面示例中的编号评论。

  1. 在混合模式下,所有空格都不应该有意义吗?为什么 a 标签之间的空格不重要?

  2. 虽然我知道实际的空白元素仍然是 XmlWhitespace,但我如何将这些空格规范化为 XmlSignificantWhitespace 节点? Normalize() 不起作用。

  3. 手动操作是我唯一的选择吗?

这是我的测试用例:

private static void Main()
{
// 1. Shouldn't all whitespace be significant in mixed mode? Why the space between the a tags is not significant?
var doc = new XmlDocument
{
InnerXml = "<root>test1 <a>test2</a> <a>test3</a></root>",
};
PrintDoc(doc);

// 2.a. While I understand that the actual whitespace element is still XmlWhitespace, how do I normalize these spaces into XmlSignificantWhitespaces?
doc.DocumentElement.RemoveAll();
doc.DocumentElement.SetAttribute("xml:space", "preserve");
var fragment = doc.CreateDocumentFragment();
fragment.InnerXml = "test1 <a>test2</a> <a>test3</a>";
doc.DocumentElement.PrependChild(fragment);
PrintDoc(doc);

// 2.b. Normalize doesn't work
doc.Normalize();
PrintDoc(doc);

// 3.a. Manual normalization does work, is there a better way?
doc.DocumentElement.RemoveAllAttributes();
var whitespaces = doc.DocumentElement.ChildNodes.Cast<XmlNode>()
.OfType<XmlWhitespace>()
.ToList();
foreach (var whitespace in whitespaces)
{
var significant = doc.CreateSignificantWhitespace(whitespace.Value);
doc.DocumentElement.ReplaceChild(significant, whitespace);
}
PrintDoc(doc);

// 3.b. Reading from string also works
doc.InnerXml = "<root xml:space=\"preserve\">test1 <a>test2</a> <a>test3</a></root>";
PrintDoc(doc);
}

private static void PrintDoc(XmlDocument doc)
{
var nodes = doc.DocumentElement.ChildNodes.Cast<XmlNode>().ToList();
var whitespace = nodes.OfType<XmlWhitespace>().Count();
var significantWhitespace = nodes.OfType<XmlSignificantWhitespace>().Count();

Console.WriteLine($"Xml: {doc.InnerXml}\nwhitespace: {whitespace}\nsignificant whitespace: {significantWhitespace}\n");
}

输出如下:

Xml: <root>test1 <a>test2</a><a>test3</a></root>
whitespace: 0
significant whitespace: 0

Xml: <root xml:space="preserve">test1 <a>test2</a> <a>test3</a></root>
whitespace: 1
significant whitespace: 0

Xml: <root xml:space="preserve">test1 <a>test2</a> <a>test3</a></root>
whitespace: 1
significant whitespace: 0

Xml: <root>test1 <a>test2</a> <a>test3</a></root>
whitespace: 0
significant whitespace: 1

Xml: <root xml:space="preserve">test1 <a>test2</a> <a>test3</a></root>
whitespace: 0
significant whitespace: 1

最佳答案

Microsoft 文档不清楚,至少部分不准确。尽管 XmlSignificantWhitespace Class 的 Microsoft 文档表示“混合内容节点中标记之间的空白” “重要空白”,实际的 XmlDocument 加载和解析行为与此不一致。相关文档是PreserveWhitespaceWhite Space and Significant White Space Handling when Loading the DOM , 但这些没有提供足够的具体细节。

根据经验,正如您通过测试用例和我自己的测试所证明的那样,行为如下:

  • XmlDocument.PreserveWhitespace = true 加载时并在 xml:space="preserve" 范围内时保留空格。然而,对于前者,它被保存在Whitespace节点而不是SignificantWhitespace节点。
  • 如果XmlDocument.PreserveWhitespace = false,则混合内容节点中元素之间的空白将被丢弃XmlSignificantWhitespace Class相反文档。
  • 空格变成xml:space="preserve" 范围内的SignfiicantWhitespace 节点。在这种情况下,无论 XmlDocument.PreserveWhitespace 设置如何,它都始终保留为 SignificantWhitespace

简而言之,将空白直接解析为 SignificantWhitespace 节点的唯一方法是在 xml:space="preserve" 范围内。一种可能对您有用的方法是将 XML 内容包装在具有 xml:space="preserve" 范围的新外部元素中。我不知道为什么您的 CreateDocumentFragment() 测试不起作用,但这里有一些代码确实有效:

// 4. Loading the XML within an xml:space="preserve" element works
doc.InnerXml = "<root xml:space=\"preserve\"></root>";
doc.FirstChild.InnerXml = "test1 <a>test2</a> <a>test3</a>";
PrintDoc(doc);

这导致:

Xml: <root xml:space="preserve">test1 <a>test2</a> <a>test3</a></root>
whitespace: 0
significant whitespace: 1

关于c# - XmlDocument:空白处理和规范化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32755795/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com