Как использовать предикаты xpath для исключения всех узлов, кроме тех, которые удовлетворяют условию? - PullRequest
3 голосов
/ 04 февраля 2011

Мне нужна помощь по использованию xpath для исключения определенных узлов из списка узлов xml.Структура XML ниже.Файл xml большой, около 8000 элементов, большинство из которых имеют тип подменю.

<Menu>
  <MenuId>2905</MenuId> 
  <Item>
     <ItemId>191916</ItemId>
     <ItemType>content</ItemType> 
  </Item>
  <Item>
     <ItemId>17343</ItemId>
     <ItemType>submenu</ItemType>
     <Menu>
         ...
     </Menu>
  </Item>
</Menu>

Что мне нужно сделать, так это для определенного MenuID (например, 2905) исключить все дочерние узлы, кроме тех, гдеItemType = 'content'

Я думал, что ниже будет работать?

Menu[MenuId !='2905' or MenuId = '2905' and child::ItemType = 'content']/Item

Разве это не должно выбрать все узлы, которые не в 2905 и любые, которые в 2905 и тип контента?Использование .NET, которое я попробовал, ниже:

        XmlNodeList nextLevelNodeList = currentNode.SelectNodes(string.Format("Menu[MenuId !='2905' or MenuId = '2905' and child::ItemType = 'content']/Item));

Любые идеи будут с благодарностью ...

ура Натан

Ответы [ 3 ]

2 голосов
/ 05 февраля 2011

Добавление одного в список выражений XPath без объединения наборов узлов:

//Menu/Item[../MenuId != 2905 or ItemType = 'content']

Значение: от любого элемента Menu, у ребенка Item есть брат или сестра MenuId, не равный 2905, или ItemType ребенок, равный 'content'

1 голос
/ 04 февраля 2011

Оба предыдущих ответа неверны .

Используйте (из родительского элемента Menu элементов):

 Menu[not(MenuId = 2905)]/Item
|
 Menu[MenuId = 2905]/Item[ItemType='content']
0 голосов
/ 04 февраля 2011

Объедините два списка узлов:

Menu[MenuId != '2905']/Item

И

Menu[MenuId = '2905']/Item[ItemType = 'content']
...