如何在C#中比较XmlDocument的两个XmlNodes?

时间:2018-05-17 05:43:33

标签: c# xml xmlnode deepequals

这是一个示例xml。如果要添加新字体,则在添加到首选项之前,要将所有现有字体与新字体进行比较。 在XmlDocument的情况下,如何检查节点(字体)是否已存在?

<preferences>
  <font role="console">
    <size>9</size>
    <fname>Courier</fname>
  </font>
  <font role="default">
    <fname>Times New Roman</fname>
    <size>14</size>
  </font>
  <font role="titles">
    <size>10</size>
    <fname>Helvetica</fname>
  </font>
</preferences>

2 个答案:

答案 0 :(得分:2)

Xnode有一个名为DeepEqual的功能来比较节点。可以通过简单的解析将XmlNode转换为Xnode。

    XElement XmlElementToXElement(XmlNode e)
    {
        return XElement.Parse(e.OuterXml);
    }

所以,从这里开始会更容易。如果两个节点相等,则以下方法将返回true。

    bool XmlNode_DeepEquals(XmlNode node1, XmlNode node2)
    {
        XElement tempX = XmlElementToXElement(node2);
        XElement searchX = XmlElementToXElement(node1);
        return XNode.DeepEquals(tempX, searchX))
    }

此方法用于比较节点列表。

    bool isNodeAlreadyExists(XmlNode searchNode, XmlNodeList list)
    {
        bool exists = false;
        foreach (XmlNode node in list)
        {
            if (XmlNode_DeepEquals(searchNode, node))
            {
                exists = true;
            }
        }
        return exists;
    }

答案 1 :(得分:1)

一种方法是创建几个类来表示XML文档并实现__next__

https://dotnetfiddle.net/QZFwDy

XML类

IEquatable<T> Interface

然后使用[XmlRoot(ElementName = "font")] public class Font : IEquatable<Font> { [XmlElement(ElementName = "size")] public string Size { get; set; } [XmlElement(ElementName = "fname")] public string Fname { get; set; } [XmlAttribute(AttributeName = "role")] public string Role { get; set; } public bool Equals(Font font) { if (font == null) return false; return (Size == font.Size) && (Fname == font.Fname) && (Role == font.Role); } } [XmlRoot(ElementName = "preferences")] public class Preferences { [XmlElement(ElementName = "font")] public List<Font> Font { get; set; } } 类反序列化XML。对文档进行反序列化后,使用Preferences方法查看字体节点是否存在。 List<T>.Contains(T item)方法会在.Contains类中调用Equals的实现。

展示代码

Font