【问题标题】:Need to extract data with xmlpath / xmlsearch需要用 xmlpath / xmlsearch 提取数据
【发布时间】:2011-12-15 15:33:58
【问题描述】:

我有这个 XML:

<?xml version="1.0" encoding="utf-8"?> 
<xml>
  <site>
    <id>123</id>
    <po>BT123</po>
  </site>
  <order>
    <shipping>
      <shippingmethod>1</shippingmethod>
      <firstname>Test</firstname>
      <lastname>User</lastname>
      <address>1234 My Place</address>
      <address2>Apt 101</address2>
      <city>Anytown</city>
      <state>AL</state>
      <zip>12345</zip>
    </shipping>
    <orderitems>
      <item>
        <isbn>9780752419930</isbn>
        <rentalterm>1</rentalterm>
      </item>
      <item>
        <isbn>0495599336</isbn>
        <rentalterm>3</rentalterm>
      </item>
      <item>
        <isbn>0743500210</isbn>
        <rentalterm>2</rentalterm>
      </item>
    </orderitems>
  </order>
</xml>

我想要做的是获取所有租期不是 2 的 ISBN 我知道如何获取所有 ISBN:

//item/isbn/text()

以及具体的租赁条款:

//item[rentalterm!=2]

但我不确定如何将它们组合在一起。有什么建议吗?

【问题讨论】:

    标签: xml xpath xml-parsing


    【解决方案1】:

    使用这个表达式:

    //item[not(rentalterm='2')]/isbn/text()
    

    英文:获取任何 isbn 元素的文本节点,该元素的父元素是 item 元素,但不具有值等于 2rentalterm 子元素 p>

    与此表达式对比:

    //item[rentalterm!=2]/isbn/text()
    

    ...转换为:获取任何isbn元素的文本节点,该元素的父元素是item元素,至少有一个rentalterm子元素的值不等于2 .

    换句话说,第二个表达式将不匹配没有rentalterm 子级的item 元素,但匹配具有多个rentalterm 子级的item 元素,只要至少一个字符串值不等于2

    换句话说,谓词[not(rentalterm='2')] 可以被解读为不包含字符串值等于2rentalterm 孩子,而[rentalterm!=2] 应该是读作包含一个rentalchild,其字符串值不等于2

    spec describes it like this

    如果要比较的一个对象是节点集,另一个是字符串, 那么当且仅当在 节点集,使得对 节点的字符串值,其他字符串为真。

    【讨论】:

    • not() 比 != 快吗?
    • 这不是速度的问题。当 item 不包含 anyrentalterm 其值为 2 时,not(rentalterm='2') 返回 true。另一方面,rentalterm!=2 使用存在量化,这意味着如果有 any rentalterm 子代不等于 2 则选择 item,即使还有另一个 @987654352 @ 其值为 2。正因为如此,not 在 XPath 中几乎总是比!= 更清晰(而且绝对更严格/安全)。 (除非您知道您打算使用!=;了解其中的区别很重要。)
    • 很棒的评论。另一种查看差异的方法是 item[rentalterm != '2'] is 等于 item/rentalterm[. != '2']/.. 但这 等于 item[not(rentalterm = '2')]
    • @jasso - 好吧,从一个匹配 item 和一个匹配 rentalterm 的意义上说,它们并不相等,但这仍然是一个有用的点。
    【解决方案2】:

    只需使用:

    //item[rentalterm!=2]/isbn/text()
    

    假设所有项目都有一个rentalterm child。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多