【问题标题】:How to compare two XmlNodes of XmlDocument in C#?如何在 C# 中比较 XmlDocument 的两个 XmlNode?
【发布时间】:2018-05-17 05:43:32
【问题描述】:

这是一个示例 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>

【问题讨论】:

  • 你好像忘了问你的问题。您可以编辑您的帖子以更清楚地说明您的要求吗?我认为您正在寻找的是 XDocument 类。
  • @JamieTwells:它在问题的标题上,它只需要一些编辑。如果你这样做,我会收回任何标志;-)
  • @JamieTwells 感谢您的关注。
  • @JamieTwells 我正在寻找 XmlDocument。

标签: c# xml xmlnode deepequals


【解决方案1】:

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;
    }

【讨论】:

【解决方案2】:

一种方法是创建几个类来表示 XML 文档并实现 IEquatable&lt;T&gt; Interface

https://dotnetfiddle.net/QZFwDy

XML 类

[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; }
}

然后使用Preferences 类来反序列化 XML。文档反序列化后,利用List&lt;T&gt;.Contains(T item) 方法查看字体节点是否存在。 .Contains 方法会调用Font 类中Equals 的实现。

演示代码

static void Main(string[] args)
{
    Preferences preferences = null;
    var xmlString = Data.XML;

    using (var stream = new StringReader(xmlString))
    {
        var serializer = new XmlSerializer(typeof(Preferences));
        preferences = (Preferences)serializer.Deserialize(stream);
    }

    var node0 = new Font()
    {
        Fname = "New One",
        Role = "console",
        Size = "12"
    };

    var node1 = new Font()
    {
        Fname = "Helvetica",
        Role = "titles",
        Size = "10"
    };

    if (preferences.Font.Contains(node0))
    {
        // Not expecting to enter here
        Console.WriteLine($"'{nameof(node0)}' is already present");
    }

    if (preferences.Font.Contains(node1))
    {
        Console.WriteLine($"'{nameof(node1)}' is already present");
    }
}

【讨论】:

    猜你喜欢
    • 2010-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-30
    • 2012-03-21
    • 1970-01-01
    • 2013-02-22
    相关资源
    最近更新 更多