XPath for all attribute values, not just first?

132 views Asked by At

Edit: the issue in my case was caused by a tool that doesn't fully implement the XPath standard. My attempt with //key@ should have worked (see comments & answer), and the reason it doesn't work is that the tool only shows the first result.

My XML looks like this:

<Document id="someIdhere" token="123-456-789" created-by="john_doe" created-at="2020-05-27T10:04:28.244+0000" last-modified-by="jane_doe" last-modified-at="2020-07-30T09:27:59.440+0000">
<somedata/>
<somemoredata/>
<entries>
    <entry key="resourceName">resourceLocation</entry>
    <entry key="foo">bar</entry>
    <entry key="somekey">somevalue</entry>
    <entry key="keyname">keyvalue</entry>
    <entry key="keyname1">value1</entry>
</entries>
<encryptedEntries/>
</Document>

I am looking to get the values of all key attributes (so 'resourcename','foo', etc) ; not the value of the <entry> nodes. There is no way in advance for me to know how many entries there will be, nor what the contents will be.

I have tried the following:

//@* -> gives all attributes, not only the key
//entries/@* -> returns nothing
//entry@* -> returns nothing
//@key -> returns only the first result
//entries/key[*] -> returns nothing
//entry@key -> returns nothing
//entry@key=* -> returns nothing

I probably tried others as well, but these are what I can remember. If it makes any difference: the XPath is executed by the 'XML Webhook' task in Xebialabs' XLRelease.

1

There are 1 answers

2
kjhughes On BEST ANSWER

@JaSON has already provided you with two viable XPaths in a comment1:

  • //@key will select all key attributes in the document.
  • //entry/@key will select all key attributes of entry elements in the document.

You've commented that //entry/@key only returns the first value and chalked it up to tool/library noncompliance. Realize that there are library APIs that have different calls for returning the first selected item versus returning all selected items.

Here are explanations for each of the attempts you made:

  • //@* selects all attributes in the document.
  • //entries/@* selects nothing because entries has no attributes.
  • //entry@* is syntactically incorrect.
  • //@key selects all key attributes in the document, but see API note above.
  • //entries/key[*] selects all key child elements (of entries elements) with at least one child element
  • //entry@key is syntactically incorrect.
  • //entry@key=* is syntactically incorrect.

1 Will upvote his answer if he posts one.