【问题标题】:Using Paths in XPath Predicates?在 XPath 谓词中使用路径?
【发布时间】:2020-10-09 19:05:09
【问题描述】:

我正在使用将商品和图像分开的 shopify 商品提要 xml。我想使用单个 xpath 获取项目的图像 url。 xml 看起来像这样-

<products>
    <product>
        <variants>
            <variant>
                <image-id>123</image-id>
            </variant>
        </variants>
    </product>
    <images>
        <image>
            <id>123</id>
            <src>https://abc/</src>
        </image>
    </images>
</products>

我的出发点是在变体中。因此,要获取图像,我可以向上两个父级,向下进入图像,获取具有匹配 id 的图像,然后从该元素获取 src。

parent::*/parent::*/images/image[id/text()="123"]/src/text()

这可行,但它被硬编码为“123”。我想要的是从变体中获取图像 ID 文本并将其用作谓词值。

parent::*/parent::*/images/image[id/text()=image-id/text()]/src/text()

XPath 至少不会抱怨这一点,但它并没有像我希望的那样工作。是否可以使用来自image-id/text() 的值作为id/text()= 的谓词值?

【问题讨论】:

  • ./../../images/image[id = ./../../product/variants/variant/image-id]/src/text()

标签: xml xpath


【解决方案1】:

由于谓词[id/text()=image-id/text()],您的原始方法不起作用。谓词在它们引用的节点的上下文中进行评估,因此在image[id/text()=image-id/text()] 的情况下,您会假设image 也有一个子节点image-id,您可以将其与id 进行比较。就我对 XPath 的理解而言,这无法单独使用 XPath 解决,因为必须以某种方式记住 variant/image-id 的上下文。

您可以通过将 variant/image-id 存储在循环内的变量中并使用它来选择正确的图像来实现此目的。

XQuery 中的示例:

for $variant in //variant return
  let $image-id := $variant/image-id
  return
    $variant//ancestor::products//image[id = $image-id]

【讨论】:

  • 这证实了我的预期——这在 XPath 中根本不可能。为了解决这个问题,我最终创建了一个自定义函数(使用 python lxml)
  • @micah - 在您的问题下查看我的评论。可以使用 xpath。它有效。
  • @AlexanderPetrov 当然,您的解决方案运行良好,并且不存储变体的上下文,而是重新选择它。我认为对于所提供的示例来说这是一个可行的解决方案,但是当我们有多个产品具有多个变体时可能会导致其他问题——然后我们必须知道变体的确切位置或创建更长的 XPath。我认为,存储上下文对于编程来说更方便。还是我在这里忽略了什么?
  • 是的,我们需要以一种或另一种方式存储上下文。在实际代码中,我不会在 xpath 中做所有事情,而是将中间值存储在某种编程语言的变量中。
【解决方案2】:

如果我理解正确,下面的表达式应该可以工作:

//images/image[id=//variant/image-id]/src/text()

输出:

https://abc/

【讨论】:

  • 我的问题可能问错了。我正在遍历变体并从变体上下文的 within 中获取图像。所以它必须使用当前上下文的//images/image[id=./image-id/text()]/src/text() - 但这不起作用,因为./ 似乎是图像......
  • .//image-id/text() 也不起作用。很奇怪
  • 恐怕我不明白——这里的“工作”是什么意思?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-06
  • 2020-01-27
  • 1970-01-01
  • 2013-10-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多