Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xml XPath按节点、子节点和子子节点条件选择节点_Xml_Xpath_Nodes_Treenode - Fatal编程技术网

Xml 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 ./

我想检索应用了节点、子节点和子子节点条件的所有节点

我尝试使用以下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>

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')]