【发布时间】:2014-12-10 16:32:32
【问题描述】:
我正在使用 JsonConvert 从从 HttpWebRequest 调用中检索到的 JSON 创建 XML。我返回的 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,但实际上都没有删除节点。
方法一:-
foreach (var duplicate in duplicateNames)
{
xNode.Elements(duplicate).Skip(1).Remove();
}
方法二:-
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)正在获取你想要删除的节点。否则请看我下面的答案,看看如何修改你的代码。