【问题标题】:XNode.DeepEquals unexpectedly returns falseXNode.DeepEquals 意外返回 false
【发布时间】:2014-06-11 07:07:50
【问题描述】:

使用XNode.DeepEquals()比较xml元素,在我认为应该等价的两个xml文档上意外返回false

示例

var xmlFromString = XDocument.Parse("<someXml xmlns=\"someNamespace\"/>");
var xmlDirect = new XDocument(new XElement(
  XNamespace.Get("someNamespace") + "someXml"));

Console.WriteLine(xmlFromString.ToString());
Console.WriteLine(xmlDirect.ToString());
Console.WriteLine(XNode.DeepEquals(xmlFromString, xmlDirect));
Console.WriteLine(xmlFromString.ToString() == xmlDirect.ToString());

输出

<someXml xmlns="someNamespace" />
<someXml xmlns="someNamespace" />
False
True

字符串被认为是相等的,但 XML 树不是。为什么?

【问题讨论】:

  • 有趣的是,DeepEquals 也仅针对根元素报告 false...所以这不是文档声明问题,例如。
  • 不,已经试过了;-)。但如果命名空间被删除,它会正确报告 true。
  • 我得出的结论是 DeepEquals() 完全不适用于比较。例如,它不同于 。这太荒谬了。

标签: c# .net xml linq-to-xml


【解决方案1】:

我已经弄清楚了区别是什么,但不是为什么不一样。

在第一种形式中,您有一个xmlns 属性。在第二种形式中,您没有 - 不是Attributes() 返回的内容。如果您显式构造一个XAttributeDeepEquals 将返回true

var xmlDirect = new XDocument(new XElement(
  XNamespace.Get("someNamespace") + "someXml",
  new XAttribute("xmlns", "someNamespace")));

基本上,在将树转换为文本表示时,就好像命名空间仅算作一个属性。

【讨论】:

  • 有趣。在我看来,DeepEquals 中的错误。一种解决方法是在字符串上反弹构造的 xml:XNode.DeepEquals(xmlFromString, XDocument.Parse(xmlDirect.ToString()) 返回 true。
  • @AndersAbel:我看不出这会是DeepEquals 中的一个错误——它的行为与记录的一样,因为这两个元素具有不同数量的属性。如果有的话,它是解析(可能不应该包含属性)或XElement 构造(可能应该包含)中的错误。不过,你有可检测到不同的树,所以DeepEquals 返回false 是公平的。
  • 你是对的。 DeepEquals 不应该受到责备。但是XElement.ToString()XDocument.Parse 的行为应该始终如一,恕我直言,要么将xmlns 视为真实属性。
【解决方案2】:

解析后你会得到一个 XDocument。尝试检索节点以在 DeepEqual 中使用它:

var xmlFromString = XDocument.Parse("").Root;

这解决了我的问题。

【讨论】:

    猜你喜欢
    • 2018-03-24
    • 1970-01-01
    • 1970-01-01
    • 2016-04-15
    • 1970-01-01
    • 2021-02-14
    • 1970-01-01
    • 1970-01-01
    • 2015-08-18
    相关资源
    最近更新 更多