Прежде всего, ваш XML
не отформатирован. У вас есть несколько корневых узлов, что недопустимо. Узлы <Table>
должны находиться под одним корневым узлом.
Тогда вы еще не совсем определили, что такое узел duplicate . Это просто дубликаты, идущие только по имени узла? Или подузлы и атрибуты узлов тоже должны быть одинаковыми?
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
. Обратите внимание, что я добавил узел _root с именем MyRoot
.
[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
, чтобы вы могли легко сравнивать несколько объектов.