0

我做了一个 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 描述了我的问题。

4

1 回答 1

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>

这需要对整个树进行递归比较。使用Distincton 元素会失败,因为它没有考虑到子元素。

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具有不同元素的新的。您现在可以将所有节点添加到模型中。

请注意,这不考虑属性。另请注意,这可能不是该工作最有效的算法。

顺便说一句:您的示例 XML 充满了错误(标签未正确关闭)。

于 2013-04-19T15:58:00.983 回答