skip to Main Content

I am working with the shopify item feed xml which has items and image separated. I’d like to get an item’s image url with a single xpath. The xml looks something like this-

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

My starting point is within the variant. So to get to the image I can go up two parents, down into images, fetch the image with the matching id, then get the src from that element.

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

This works, but it’s hard coded to "123". What i’d like is to take the image-id text from the variant and use that as the predicate value.

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

XPath at least doesn’t complain about this, but it doesn’t work as I was hoping. Is it possible to use the value from image-id/text() as the predicate value for id/text()= ?

2

Answers


  1. If I understand you correctly, the following expression should work:

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

    Output:

    https://abc/
    
    Login or Signup to reply.
  2. Your original approach doesn’t work because of the predicate [id/text()=image-id/text()]. Predicates are evaluated in the context of the node they refer to, so in case of image[id/text()=image-id/text()] you’d assume that image also has a child node image-id which you compare with id. As far as my understanding of XPath goes, this isn’t solvable with XPath alone since the context of variant/image-id has to be remembered somehow.

    You could achieve this by storing your variant/image-id in a variable within your loop and use this for selecting the correct image.

    Example in XQuery:

    for $variant in //variant return
      let $image-id := $variant/image-id
      return
        $variant//ancestor::products//image[id = $image-id]
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search