如何使用C#代码消除重复的XML节点

时间:2018-09-05 16:14:16

标签: c# xml linq duplicates element

我有一个模式XML文件,其中包含表,列和外键的节点,如下所示。

axios

因此,就像上面观察到的,它包含重复的元素(最后两个外键)。我是LINQ的新手。有人可以分享一个示例,使用该示例我可以从XML文件中删除此重复元素。

1 个答案:

答案 0 :(得分:0)

首先,您的XML格式不正确。您有多个根节点,这是非法的。 <Table>节点应位于一个根节点下。

然后,您尚未完全定义重复节点是什么。它是否仅按节点名称重复复制?还是子节点的子节点和属性也必须相同?

1。仅节点(元素)名称重复

这很容易。您将获得该名称的所有元素,然后执行Skip(1)首先跳过 ,然后删除其余部分。

XDocument xDoc = XDocument.Load("data.xml");
xDoc.Root.Descendants("ForeignKey").Skip(1).Remove();

现在XML看起来像这样:

<MyRoot>
  <Table schema="Reports_vN" name="pstpyr" caption="PR Payroll Posting">
    <Column name="recnum" alias="Record Number" isprimarykey="1" />
    <Column name="pstnum" alias="Posting Number" />
  </Table>
  <Table schema="Reports_vN" name="payrec" caption="PR Payroll Record">
    <Column name="recnum" alias="Record Number" isprimarykey="1" />
    <Column name="empnum" alias="Employee" />
    <Column name="strprd" alias="Period Start" />
    <ForeignKey pkSchema="Reports_vN" pkTable="payrec" fkSchema="Reports_vN" fkTable="tmcdln" name="Record Number">
      <ForeignKeyCol pkCol="recnum" fkCol="recnum" />
    </ForeignKey>
  </Table>
</MyRoot>

2。彻底检查,包括子元素和属性

我说,您最好的选择是使用Deserialization。首先,您需要创建一组与XML格式匹配的类。外观取决于您提供的XML。请注意,我添加了一个名为MyRoot的_root节点。

[XmlRoot("MyRoot")]
public class MyRoot
{
    [XmlElement("Table")]
    public List<Table> Tables { get; set; }
}

public class Table
{
    [XmlAttribute("schema")]
    public string Schema { get; set; }
    [XmlAttribute("name")]
    public string Name { get; set; }
    [XmlAttribute("caption")]
    public string Caption { get; set; }

    [XmlElement("Column")]
    public List<Column> Columns { get; set; }

    [XmlElement("ForeignKey")]
    public List<ForeignKey> ForeignKeys { get; set; }
}

public class Column
{
    [XmlAttribute("name")]
    public string Name { get; set; }
    [XmlAttribute("alias")]
    public string Alias { get; set; }
    [XmlAttribute("isprimarykey")]
    public string IsPrimaryKey { get; set; }
}

public class ForeignKey
{
    [XmlAttribute("pkSchema")]
    public string PkSchema { get; set; }
    [XmlAttribute("pkTable")]
    public string PkTable { get; set; }
    [XmlAttribute("fkSchema")]
    public string FkSchema { get; set; }
    [XmlAttribute("fkTable")]
    public string FkTable { get; set; }
    [XmlAttribute("name")]
    public string Name { get; set; }

    [XmlElement("ForeignKeyCol")]
    public ForeignKeyCol ForeignKeyCol { get; set; }
}

public class ForeignKeyCol
{
    [XmlAttribute("pkCol")]
    public string PkCol { get; set; }
    [XmlAttribute("fkCol")]
    public string FkCol { get; set; }
}

现在,您可以使用以下方法反序列化XML

public static T DeserializeXMLFileToObject<T>(string XmlFilename)
{
    T returnObject = default(T);
    if (string.IsNullOrEmpty(XmlFilename)) return default(T);

    try
    {
        StreamReader xmlStream = new StreamReader(XmlFilename);
        XmlSerializer serializer = new XmlSerializer(typeof(T));
        returnObject = (T)serializer.Deserialize(xmlStream);
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
    return returnObject;
}

这样称呼它:

MyRoot xml = DeserializeXMLFileToObject<MyRoot>("data.xml");

现在,只需使用简单的C#技术来查找和删除重复项即可。最简单的方法是编写一个Comparer,以便您可以轻松比较多个对象。