XElement.Descendants(“Node”)的行为不符合预期,返回多个级别的后代

时间:2009-11-18 03:56:32

标签: c# sql xml xelement

我有一个问题。我有分层XML数据,例如:

<Tree>
  <Node Text="Stuff" ItemGUID="064a9bf0-0594-47f8-87be-88dd73763c77" >
    <Node Text="Food" ItemGUID="326f1f7a-d364-4838-9bdc-ce5fd93f88ca" ItemType="2" />
    <Node Text="Wines" ItemGUID="950e3ca3-27a1-41fd-89f3-7a8b08633a9f" />
    <Node Text="Flowers" ItemGUID="cefa8c34-af06-48e7-9c00-4b1422d217a4">
        <Node Text="Roses" ItemGUID="950e3ca3-27a1-41fd-89f3-7a8b08633a9f">
              <Node Text="Red" ItemGUID="950e3ca3-27a1-41fd-89f3-7a8b08633a9f" />
              <Node Text="Pink" ItemGUID="950e3ca3-27a1-41fd-89f3-7a8b08633a9f" />
              <Node Text="White" ItemGUID="950e3ca3-27a1-41fd-89f3-7a8b08633a9f" />
        </Node>
        <Node Text="Tulips" ItemGUID="950e3ca3-27a1-41fd-89f3-7a8b08633a9f" />
        <Node Text="Whatever" ItemGUID="950e3ca3-27a1-41fd-89f3-7a8b08633a9f" />
    </Node>
    <Node Text="Sweet Delights" ItemGUID="1df7dbae-adf0-49a9-aaac-1358468a245b" />
  </Node>
</Tree>

我需要得到鲜花(玫瑰,郁金香,无论如何),没有红色,粉红色,白色(玫瑰下)  我正在使用以下代码,但由于所有节点都是“节点”,我得到了所有级别的后代。我想将其限制在一个级别。

XElement loadedXML = clients.ItemTreeXML;

//filter only current node
XElement procXML;
procXML = new XElement ("Tree",
          from el in loadedXML.Descendants("Node")
          where (string)el.Attribute("ItemGUID") == currentNodeGUID
          select el); 

结果通缉:

<Tree>
        <Node Text="Flowers" ItemGUID="cefa8c34-af06-48e7-9c00-4b1422d217a4">
            <Node Text="Roses" ItemGUID="950e3ca3-27a1-41fd-89f3-7a8b08633a9f" />
            <Node Text="Tulips" ItemGUID="950e3ca3-27a1-41fd-89f3-7a8b08633a9f" />
            <Node Text="Whatever" ItemGUID="950e3ca3-27a1-41fd-89f3-7a8b08633a9f" />
        </Node>
</Tree>

谢谢,

补充:也许SQL 2008查询只能检索我需要的节点分支,但经过大量的研究和测试后,我找不到答案......(我的XML在SQL 2008的XML列中)

1 个答案:

答案 0 :(得分:0)

所以我们有这个...

XElement loadedXML = XElement.Load("test.xml");

//filter only current node
XElement procXML;
procXML = new XElement("Tree",
    from el in loadedXML.Descendants("Node")
    where (string)el.Attribute("ItemGUID") == currentNodeGUID
    select el);

我发现的最佳方法是在执行LINQ查询后删除所有子元素。像这样:

foreach (XElement xl in procXML.Element("Node").Elements("Node"))
{
    if (xl.HasElements) // just remove the ones without child elements
    {
        xl.RemoveNodes();
    }
}

这将输出您想要的内容,但我必须添加... 最明确是更好的方法。我不知道它对你的情况有多好,因为大多数代码编写需要比这更有效地工作。

我看到了这个问题并决定潜入Linq,我想这并不是那么糟糕。如果这不能正常运作,至少它是一个开始。