Я создаю XML из JSON, полученного из вызова HttpWebRequest, с помощью JsonConvert. JSON, который я возвращаю, иногда имеет повторяющиеся узлы, что создает повторяющиеся узлы в XML после преобразования, которые затем мне нужно удалить.
Обработка преобразования JSON в XML выполняется в универсальной оболочке вызова службы, которая не знает базовой структуры данных и поэтому не может выполнять какие-либо запросы XPath на основе именованного узла. Дубликаты могут быть на любом уровне в XML.
Я дошел до стадии, когда у меня есть список имен повторяющихся узлов на каждом уровне, но я не уверен, что запрос Linq может использовать это для удаления всех узлов, кроме первого, с таким именем.
Мой код:
protected virtual void RemoveDuplicateChildren(XmlNode node)
{
if (node.NodeType != XmlNodeType.Element || !node.HasChildNodes)
{
return;
}
var xNode = XElement.Load(node.CreateNavigator().ReadSubtree());
var duplicateNames = new List<string>();
foreach (XmlNode child in node.ChildNodes)
{
var isBottom = this.IsBottomElement(child); // Has no XmlNodeType.Element type children
if (!isBottom)
{
this.RemoveDuplicateChildren(child);
}
else
{
var count = xNode.Elements(child.Name).Count();
if (count > 1 && !duplicateNames.Contains(child.Name))
{
duplicateNames.Add(child.Name);
}
}
}
if (duplicateNames.Count > 0)
{
foreach (var duplicate in duplicateNames)
{
xNode.Elements(duplicate).SelectMany(d => d.Skip(1)).Remove();
}
}
}
Последняя строка кода явно неверна, но я не могу найти пример того, как ее переработать, чтобы получить, а затем удалить все, кроме первого совпадающего элемента.
ОБНОВЛЕНИЕ: я нашел два способа сделать это сейчас, один с использованием XElement и один с XmlNode, но на самом деле ни один из них не удаляет узлы.
Метод 1: -
foreach (var duplicate in duplicateNames)
{
xNode.Elements(duplicate).Skip(1).Remove();
}
Способ 2: -
foreach (var duplicate in duplicateNames)
{
var nodeList = node.SelectNodes(duplicate);
if (nodeList.Count > 1)
{
for (int i=1; i<nodeList.Count; i++)
{
node.RemoveChild(nodeList[i]);
}
}
}
Что мне не хватает?
duplicateNames
имеет все повторяющиеся имена, и две, что вашxNode.Elements(duplicate)
получает узлы, которые вы хотите удалить. В противном случае посмотрите мой ответ ниже, чтобы узнать, как изменить свой код. - person Chuck Savage   schedule 10.12.2014