【发布时间】:2016-03-19 17:56:15
【问题描述】:
这是给定的xml:
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Root>
<WorkItem>
<Id>716</Id>
<WorkItemType>Product Backlog Item</WorkItemType>
<TreeLevel>0</TreeLevel>
<Children>
<WorkItem>
<Id>717</Id>
<WorkItemType>Product Backlog Item</WorkItemType>
<TreeLevel>1</TreeLevel>
<Children>
<WorkItem>
<Id>719</Id>
<WorkItemType>Product Backlog Item</WorkItemType>
<TreeLevel>2</TreeLevel>
<Children>
<WorkItem>
<Id>721</Id>
<WorkItemType>Task</WorkItemType>
<TreeLevel>3</TreeLevel>
<Children />
</WorkItem>
</Children>
</WorkItem>
<WorkItem>
<Id>720</Id>
<WorkItemType>Product Backlog Item</WorkItemType>
<TreeLevel>2</TreeLevel>
<Children>
<WorkItem>
<Id>724</Id>
<WorkItemType>Task</WorkItemType>
<TreeLevel>3</TreeLevel>
<Children />
</WorkItem>
</Children>
</WorkItem>
<WorkItem>
<Id>723</Id>
<WorkItemType>Task</WorkItemType>
<TreeLevel>2</TreeLevel>
<Children>
<WorkItem>
<Id>744</Id>
<WorkItemType>Task</WorkItemType>
<TreeLevel>3</TreeLevel>
<Children>
<WorkItem>
<Id>747</Id>
<WorkItemType>Task</WorkItemType>
<TreeLevel>4</TreeLevel>
<Children />
</WorkItem>
</Children>
</WorkItem>
</Children>
</WorkItem>
<WorkItem>
<Id>748</Id>
<WorkItemType>Task</WorkItemType>
<TreeLevel>2</TreeLevel>
<Children />
</WorkItem>
<WorkItem>
<Id>752</Id>
<WorkItemType>Product Backlog Item</WorkItemType>
<TreeLevel>2</TreeLevel>
<Children>
<WorkItem>
<Id>753</Id>
<WorkItemType>Product Backlog Item</WorkItemType>
<TreeLevel>3</TreeLevel>
<Children />
</WorkItem>
</Children>
</WorkItem>
</Children>
</WorkItem>
<WorkItem>
<Id>718</Id>
<WorkItemType>Task</WorkItemType>
<TreeLevel>1</TreeLevel>
<Children />
</WorkItem>
</Children>
</WorkItem>
</Root>
简化的xml是这样的
716 (PBI) Root
- 717 (PBI)
- 719 (PBI)
- 721 (Task)
- 720 (PBI)
- 724 (Task)
- 723 (Task)
- 744 (Task)
- 747 (Task)
- 748 (Task)
- 752 (PBI)
- 753 (PBI)
- 718 (Task)
我想检索 WorkItemType "Product Backlog Item" 的所有第二个内部节点。 我也可以说我想要“Product Backlog Items”,其中包含“Product Backlog Item”类型的子元素,但没有“Product Backlog Item”的子元素。
在给定的示例中,这将是
我尝试用这个 xpath 命令接收它(我在 C# 中使用 System.Xml.XmlDocument):
//WorkItem[WorkItemType[text()='Product Backlog Item'] and ./Children/WorkItem/WorkItemType[text() = 'Product Backlog Item'] and not(./Children//WorkItem/WorkItemType[text() = 'Product Backlog Item']/Children/WorkItem/WorkItemType[text() = 'Product Backlog Item'])]
为了更好的可读性
//WorkItem[WorkItemType[text()='Product Backlog Item']
and ./Children/WorkItem/WorkItemType[text() = 'Product Backlog Item']
and not(./Children//WorkItem/WorkItemType[text() = 'Product Backlog Item']/Children/WorkItem/WorkItemType[text() = 'Product Backlog Item'])]
通过这个 XPath 表达式,我得到了 ID 为 716、717 和 752 的项目。
但我只想要 752 项。
【问题讨论】:
-
你为什么不使用
LINQ TO XML呢? -
@Sybren 感谢您的评论。我使用 xpath 是因为我将 xpath 表达式存储在配置文件中。以后需要扩展这个文件。据我所知
LINQ TO XML这是不可能的。 -
能否详细说明“第二个内部节点”?
-
@YacoubMassad 感谢您的评论。我试图描述它。如果您检查简化的 xml 结构,我想选择 752。这是 PBI(产品待办事项)类型的第二个最内层节点。
-
我想我找到了解决这个查询问题的方法: //WorkItem[WorkItemType[text()='Product Backlog Item'] and Children/WorkItem/WorkItemType[text() = 'Product Backlog Item'] 而不是(Children/WorkItem/WorkItemType[text() != 'Product Backlog Item'])]
标签: c# xml xpath nodes treenode