Xml XPath按节点、子节点和子子节点条件选择节点
我想检索应用了节点、子节点和子子节点条件的所有节点 我尝试使用以下xpath命令接收它:Xml XPath按节点、子节点和子子节点条件选择节点,xml,xpath,nodes,treenode,Xml,Xpath,Nodes,Treenode,我想检索应用了节点、子节点和子子节点条件的所有节点 我尝试使用以下xpath命令接收它: xmlDoc.SelectNodes("//WorkItem[WorkItemType[text()='Product Backlog Item'] and ./Childern/WorkItem/WorkItemType[text() = 'Task'] and /Childern/WorkItem/WorkItemType[text() != 'Product Backlog Item'] and ./
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>
716
产品Backlog项
717
产品Backlog项
719
产品Backlog项
721
任务
722
任务
720
产品Backlog项
2.
724
任务
726
任务
723
任务
744
任务
更新
根据Rolf Rander的意见,我补充了一些解释:
- 我想要WorkItemType“Product Backlog Item”的WorkItem元素,它只包含WorkItemType“Task”的WorkItem元素作为任何类型的子元素(子元素、孙辈、孙辈等…)
(我纠正了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为“产品待办事项”,且
- 在名为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'])
如果至少有一个工作项类型
与标准匹配(第一个文本节点子项不等于“产品待办事项”
),则前者的计算结果为true
。将其与后者进行对比,后者仅在没有工作项类型
与标准匹配时才计算为true
(第一个文本节点子项等于“产品待办事项”
)
因此,完整的XPath如下所示(格式化为可读性):
更新:
在回答更新后的问题时,我会这样做:
//WorkItem[WorkItemType[text()='Product Backlog Item']]
[not(.//WorkItem/WorkItemType/text() != 'Task')]
你好,罗尔夫,谢谢你的回答。你完全正确地回答了我的问题。我希望有类型为“Product Backlog Item”的工作项元素,它只具有与任何类型的子项(子项、孙子项、孙子项等)相同的任务。设计时还不清楚儿童的深度。我已经更新了我的问题。这并没有返回ID723,我想这是你想要的。谢谢你的回复。我也研究了罗尔夫·兰德的安瓦尔。看来两者都管用。/Childern(在/之前的点表示规则将应用于已过滤的节点元素??)是否正确。请检查我更新的问题,也许有更聪明的方法来完成我的任务。是的,开头的点表示应该从当前上下文元素处理以下XPath表达式。或者,您可以直接说
Children/..
//WorkItem[WorkItemType[text()='Product Backlog Item']]
[not(.//WorkItem/WorkItemType/text() != 'Task')]