我做了一个Linq语句,希望收到XML文件的所有节点。
foreach (var node in epaXmlLoad.Root.Descendants()
.DescendantNodes()
.OfType<XElement>()
.Distinct())
{
newEntity = true;
xmlModel.Node = node.Name.ToString();
xmlModel.ParentNode = node.Parent.Name.ToString();
model.Save(xmlModel);
}
这会将节点和该节点的父节点保存在表中。
但是当我运行它时,表中会有重复的数据。 我无法区分节点值,因为有更多的子节点具有相同的名称,但上面有其他父节点。
<EPC>
<General>
<Input>3</Invoer>
<Amount>3</Amount>
<Name>Bla</Name>
</General>
<Sectors>
<Sector>
<Name>Blalbla</Perc>
<UsageID>0</UsageID>
<Detection>0</Detection>
<Sector>
<Sector>
<Name>Blalbla</Perc>
<UsageID>0</UsageID>
<Detection>0</Detection>
<Sector>
<Sectors>
<Devices>
<Device>
<Name>Bladiebla</name>
<Amount>5</Amount>
<Detection>True</Detection>
</Device>
<Device>
<Name>Bladiebla2</name>
<Amount>5</Amount>
<Detection>True</Detection>
</Device>
<Devices>
^这个XML描述了我的问题。
答案 0 :(得分:0)
虽然您的问题对预期结果不是很清楚,但您似乎正在尝试从XML中删除重复的节点。
XML:
<Parent>
<Child>
<Value>42</Value>
</Child>
<Child>
<Value>stackoverflow</Value>
</Child>
<Child>
<Value>stackoverflow</Value>
<Grandchild>17</Grandchild>
</Child>
<Child>
<Value>42</Value>
</Child>
</Parent>
应转换为:
<Parent>
<Child>
<Value>42</Value>
</Child>
<Child>
<Value>stackoverflow</Value>
</Child>
<Child>
<Value>stackoverflow</Value>
<Grandchild>17</Grandchild>
</Child>
</Parent>
这需要对整棵树进行递归比较。在元素上使用Distinct
将失败,因为它不会考虑孩子。
public static XElement Reduce(XElement root)
{
XElement result = new XElement(root.Name);
result.Add(root.Nodes().OfType<XText>());
List<XElement> children = new List<XElement>();
foreach (var child in root.Elements())
{
var reducedChild = Reduce(child);
if (!children.Any(c => IsDuplicate(c, reducedChild)))
{
children.Add(reducedChild);
}
}
result.Add(children);
return result;
}
public static bool IsDuplicate(XElement element1, XElement element2)
{
if (element1.Name != element2.Name || element1.Value != element2.Value)
{
return false;
}
var children1 = element1.Elements();
var children2 = element2.Elements();
if (children1.Count() != children2.Count())
{
return false;
}
return children1.Zip(children2, (c1, c2) => IsDuplicate(c1, c2)).All(isDup => isDup);
}
在Reduce
的根目录上调用XDocument
将构建一个包含不同元素的新XElement
。您现在可以将所有节点添加到模型中。
请注意,这不会考虑属性。还要注意,这可能不是最有效的算法。
BTW:您的示例XML充满了错误(标签未正确关闭)。