XPath select 逐节点、子节点和子子节点条件
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']]");
这没有提供任何节点。但我希望 WorkItem 节点的 ID 为: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 的意见,我添加了更多解释:
- 我想要 WorkItem-elements 的 WorkItemType 'Product Backlog Item' 它只有 WorkItem-Elements 的 WorkItemType 'Task' 作为任何一种 children (children, grandchildren grandgrandchildren 等等...).
children 封装的级别在设计时尚不清楚。我已经更新了我的问题。
(我在 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']
]
您对 "equal to 'Task'" 进行了两次测试,不必同时检查它是否等于 'Task' 和是否不同于 'Product Backlog Item'。
您可以使用 // 检查 "any children or grandchildren",因此:
- 任何工作项
- WorkItemType = 'Product Backlog Item',并且
- 名称为 WorkItemType 且内容为 'Task'
的子项下没有节点
可以翻译成:
//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'
).将它与后者进行对比,后者仅在没有 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')]
我想检索应用了节点、子节点和子子节点条件的所有节点
我试图用这个 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']]");
这没有提供任何节点。但我希望 WorkItem 节点的 ID 为: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 的意见,我添加了更多解释:
- 我想要 WorkItem-elements 的 WorkItemType 'Product Backlog Item' 它只有 WorkItem-Elements 的 WorkItemType 'Task' 作为任何一种 children (children, grandchildren grandgrandchildren 等等...).
children 封装的级别在设计时尚不清楚。我已经更新了我的问题。 (我在 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']
]
您对 "equal to 'Task'" 进行了两次测试,不必同时检查它是否等于 'Task' 和是否不同于 'Product Backlog Item'。
您可以使用 // 检查 "any children or grandchildren",因此:
- 任何工作项
- WorkItemType = 'Product Backlog Item',并且
- 名称为 WorkItemType 且内容为 'Task' 的子项下没有节点
可以翻译成:
//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'
).将它与后者进行对比,后者仅在没有 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')]