【问题标题】:How do I use xpath predicates to exclude all nodes except those that meet a condition?如何使用 xpath 谓词排除除满足条件的节点之外的所有节点?
【发布时间】:2011-02-04 05:19:31
【问题描述】:

我需要使用 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));

任何想法将不胜感激......

干杯 内森

【问题讨论】:

    标签: .net xml xpath predicate


    【解决方案1】:

    将一个添加到 XPath 表达式列表中,没有节点集联合:

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

    含义:从任何Menu 元素中,Item 子元素的兄弟MenuId 不等于2905ItemType 子元素等于'content'

    【讨论】:

      【解决方案2】:

      之前的两个答案都不正确

      使用(来自Menu 元素的父级):

       Menu[not(MenuId = 2905)]/Item
      |
       Menu[MenuId = 2905]/Item[ItemType='content']
      

      【讨论】:

      • 嗨 @Dimitre 这会起作用,但我不确定如何将表达式转换为我的 NodeList 定义 XmlNodeList nextLevelNodeList = currentNode.SelectNodes(string.Format("Menu/Item[ItemLevel={0} ]", iLevel));我不能在 string.format 中使用 or 运算符,可以吗?
      • @Nathan:当然可以——它是字符串的一部分:string.Format("Menu[not(MenuId = {0}) | Menu[MenuId = {0}]/Item[ItemType='content']]", iLevel)顺便说一句,这不是“或”而是联合运算符。
      • 不错,效果很好。更复杂的是,我可以将一系列 MenuId 存储在一个数组中,并在 string.Format 中使用它吗?就像下面的伪代码... int[] menuIdArray = {2905, 323, 43453}; Menu[not(MenuId in MenuIdArray) 认为对未来的菜单进行验证以允许跨多个菜单应用解决方案是明智之举
      • 是的,在 XSLT 中可以做到这一点。同样在 XPath 2.0 中。请提出一个新的、单独的问题
      【解决方案3】:

      合并两个节点列表:

      Menu[MenuId != '2905']/Item
      

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

      【讨论】:

        猜你喜欢
        • 2015-10-29
        • 1970-01-01
        • 1970-01-01
        • 2019-01-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多