XDocument确定父节点的最后一个子节点。

3
使用XDocument遍历XML文档的子元素,如何确定当前子元素是其父元素的最后一个子元素?
XDocument xmlDoc = XDocument.Parse(xml)

  foreach (var element in xmlDoc.Descendants())
        {
           //Need to determine the last child of the parent and do something here. 
        }

XML示例及预期返回结果。我需要动态遍历文档,而不指定XPath或Xquery,因为这些将通用地用于各种XML文档,而不涉及太多细节...只是想看看是否可以使用XDocument来实现这一点,或者是否有更好的方法,仍然不指定XPath或XQuery中的标记名称,除非可以在不知道文档可能有多少级深度的情况下动态完成。

<?xml version="1.0"?>
<Root> 
<Customer>
<CustID>1</CustID>
<Name>Smith, Joe</Name>
<CustomerTransDetail>
<CustID>1</CustID>
<CustTransID>1</CustTransID>
<Note>NA</Note>
</CustomerTransDetail>
<CustomerTransDetail>
<CustID>1</CustID>
<CustTransID>2</CustTransID>
<Note>N/A</Note>
</CustomerTransDetail>
</Customer>
<Customer>
<CustID>2</CustID>
<Name>Smith, Jane</Name>
<CustomerTransDetail>
<CustID>2</CustID>
<CustTransID>1</CustTransID>
<Note>N/A</Note>
</CustomerTransDetail>
<CustomerTransDetail>
<CustID>2</CustID>
<CustTransID>2</CustTransID>
<Note>N/A</Note>
</CustomerTransDetail>
</Customer>
</Root>

我需要知道何时到达父级的最后一个子节点,以便可以执行某些操作。例如,每次到达Name节点或Note节点时我都可以做一些事情。


所以每次我点击Name节点或Note节点时,例如,我都可以做些什么。不清楚为什么“Name”节点会有资格,因为在您的示例XML中,在这两种情况下都跟随一个兄弟节点。 - Sergey Kalinichenko
我需要更加具体一些......当我到达层级结构的末尾并遇到一个兄弟或没有兄弟的父节点时,我需要执行某些操作。在循环过程中,我认为我需要向前读取并确认它是否是兄弟关系(真正确定它们之间的关系),但不确定如何去做。 - PMOrion
我没明白。你想要每个“Name”节点和每个“Note”节点吗? - Batuu
2个回答

2

我还不太清楚你想要做什么,但希望这可以指引你走向正确的方向。

你正在使用XDocument,所以我假设你至少在.NET 3.5以上。你很可能可以使用Linq to XML扩展方法来实现你想要的功能。

XDocument doc = XDocument.Parse("xmlPath");
foreach (XElement element in doc.Root.Descendants())
{
    bool hasChildren = element.HasElements;
    bool hasSiblings = element.ElementsBeforeSelf().Any() || element.ElementsAfterSelf().Any();
    bool isLastChild = hasSiblings && !element.ElementsAfterSelf().Any();
}

根据您遍历节点时需要完成的任务,可以考虑在遍历树时使用递归。这样,您可以在行进过程中确定该元素是否有兄弟姐妹、是否为最后一个兄弟姐妹等。

我相信这会帮我到达目的地。我正在寻找一种方法,使 XDocument 可以智能地读取 XML,以便根据需要注入方法调用。 - PMOrion

0

您可以使用linq查询来获得与CB答案相同的结果,而无需引入所有布尔值:

    var query = from element in doc.Descendants()
                where element.ElementsBeforeSelf().Any() && !element.ElementsAfterSelf().Any() 
                select element;

    foreach (XElement element in query)
    {
      // Do something ...
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接