XPath for value given key?

Viewed 258

I have an XML object created from the below:

<?xml version="1.0" encoding="UTF-8"?>
<pdfDoc>
  <XMLOutput>
    <webservice>
      <residentLocationData>
        <addressDataMap>
          <entry>
            <key>Zip</key>
            <value>08094</value>
          </entry>
          <entry>
            <key>CountyCode</key>
            <value>015</value>
          </entry>
          <entry>
            <key>StateName</key>
            <value>New Jersey</value>
          </entry>
        </addressDataMap>
      </residentLocationData>
    </webservice>
  </XMLOutput>
<pdfDoc>

And I'm trying to extract the string value of "New Jersey". To get the "value" element itself, I'm using:

//addressDataMap/entry/key[text() = 'StateName']/following-sibling::value

But I haven't seen anything online that says how to get the string value of that element's xmlText, using just XPath itself. I CAN get that string using code from the language I'm working with (Coldfusion):

<cfset theState = xmlSearch(L.xmlObj, "//addressDataMap/entry/key[text() = 'StateName']/following-sibling::value")[1].xmlText>

but I'm not clear on how to get only the string "New Jersey" using just XPath.

4 Answers

This XPath,

//entry[key='StateName']/value/text()

will select "New Jersey" value associated with the 'StateName' key, as requested.

//addressDataMap/entry/key[text() = 'StateName']/following-sibling::value/text()

or

string(//addressDataMap/entry/key[text() = 'StateName']/following-sibling::value)

should work.

Try using

//addressDataMap/entry[key/text()='StateName']/value/text()

It should give you the string "New Jersey".

I've tried the suggested Xpaths. Using the ones that end with "/text()", I'm not getting back a string, but rather a one-element array that contains a structure with three kv pairs:

XmlName = #text
XmlType = TEXT
XmlValue = New Jersey

It may be because I'm using the Coldfusion function xmlSearch(). This is supposed to return the same datatype as what the XPath expression would return, but maybe it's not in this case. But that's fine. Easy enough to get a string with:

<cfset strState = xmlSearch(L.xmlObj, "//workLocationData/addressDataMap/entry[key/text() = 'StateName']/value/text()")[1].xmlValue>

and this is better than using "following-sibling" as I was using before, just in case the "value" element ever comes before its sibling "key" element.

Related