繁体   English   中英

XPath按节点,子节点和子子节点条件选择节点

[英]XPath select node by node, subnode and subsubnode condition

我想检索所有已应用节点,子节点和子子节点条件的节点

我试图通过以下xpath命令接收它:

xmlDoc.SelectNodes("//WorkItem[WorkItemType[text()='Product Backlog Item'] and ./Childern/WorkItem/WorkItemType[text() = 'Task'] and /Childern/WorkItem/WorkItemType[text() != 'Product Backlog Item'] and ./Childern/WorkItem/WorkItemType[text() = 'Task']]");

这没有提供任何节点。 但是我希望带有ID的WorkItem节点为:719和720,但不是717

如何在XPath中表达这一点?

给定的xml看起来像这样:

<?xml version="1.0" encoding="utf-8"?>
<root>
    <id>716</id>
    <WorkItemType>Product Backlog Item</WorkItemType>
    <Children>
        <WorkItem>
            <id>717</id>
            <WorkItemType>Product Backlog Item</WorkItemType>
            <Children>
                <WorkItem>
                    <id>719</id>
                    <WorkItemType>Product Backlog Item</WorkItemType>
                    <Children>
                        <WorkItem>
                            <id>721</id>
                            <WorkItemType>Task</WorkItemType>
                            <Children>
                                <WorkItem>
                                    <id>722</id>
                                    <WorkItemType>Task</WorkItemType>
                                    <Children/>
                                </WorkItem>
                            </Children>
                        </WorkItem>
                    </Children>
                </WorkItem>
                <WorkItem>
                    <id>720</id>
                    <WorkItemType>Product Backlog Item</WorkItemType>
                    <TreeLevel>2</TreeLevel>
                    <Children>
                        <WorkItem>
                            <id>724</id>
                            <WorkItemType>Task</WorkItemType>
                            <Children>
                                <WorkItem>
                                    <id>726</id>
                                    <WorkItemType>Task</WorkItemType>
                                    <Children/>
                                </WorkItem>
                            </Children>
                        </WorkItem>
                    </Children>
                </WorkItem>
                <WorkItem>
                    <id>723</id>
                    <WorkItemType>Task</WorkItemType>
                    <Children>
                        <WorkItem>
                            <id>744</id>
                            <WorkItemType>Task</WorkItemType>
                            <Children/>
                        </WorkItem>
                    </Children>
                </WorkItem>
            </Children>
        </WorkItem>
    </Children>
</root>

更新

由于Rolf Rander的投入,我添加了更多解释:

  • 我想让WorkItemType'Product Backlog Item'的WorkItem-elements仅具有WorkItemType'Task'的WorkItem-Elements作为任何子项(子项,孙子项,grandgrandchildren等等)。

在设计时尚不清楚儿童包裹的深度。 我已经更新了我的问题。 (并且我纠正了xml文件中的错字Childern-> Children)。

尚不清楚要实现的目标,但是重新格式化代码似乎有几个冗余测试:

//WorkItem[
WorkItemType[text()='Product Backlog Item'] and
./Childern/WorkItem/WorkItemType[text() = 'Task'] and
/Childern/WorkItem/WorkItemType[text() != 'Product Backlog Item'] and
./Childern/WorkItem/WorkItemType[text() = 'Task']
]

您两次测试“等于'任务'”,并且不必同时检查它是否等于“任务”并且与“产品待办事项”不同。

您可以使用//检查“任何子孙”,因此:

  • 任何工作项
  • 与WorkItemType ='Product Backlog Item',和
  • 在子节点下没有名称为WorkItemType且内容为“任务”的节点

可以翻译成:

//WorkItem[
     WorkItemType[text()='Product Backlog Item'] and
     not(Children//WorkItemType[text() != 'Task'])
]

代替这个

./Childern/WorkItem/WorkItemType[text() != 'Product Backlog Item']

用这个:

not(./Childern/WorkItem/WorkItemType[text() = 'Product Backlog Item'])

如果至少有一个WorkItemType与条件匹配(前一个文本节点的子级不等于 'Product Backlog Item' ),则前者的评估结果为true 将其与后者进行比较,后者仅在不存在符合条件的WorkItemType时才评估为true (其第一个文本节点子级等于 'Product Backlog Item' )。

因此,完整的XPath看起来像这样(为便于阅读而设置):

//WorkItem[
    WorkItemType[text()='Product Backlog Item'] 
        and 
    ./Childern/WorkItem/WorkItemType[text() = 'Task'] 
        and 
    not(./Childern/WorkItem/WorkItemType[text() = 'Product Backlog Item']) 
        and 
    ./Childern/WorkItem/WorkItemType[text() = 'Task']
]

更新:

为了回应更新的问题,我将执行以下操作:

//WorkItem[WorkItemType[text()='Product Backlog Item']]
          [not(.//WorkItem/WorkItemType/text() != 'Task')]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM