xmlxpath

XML - XPath 1.0 getting value based of matching another value


I am attempting to extract the CVE-2011-3389 <reference> value from this bunch of XML based on the <type> tag and its value.

If <type> == cve, grab the text() value from <reference>, if not, skip. The CVE is not always the 5th node, so I cannot use node counting to obtain the correct one.

<references>
  <reference>
    <type>other</type>
    <title/>
    <reference>CWE:327</reference>
    <description/>
    <url/>
  </reference>
  <reference>
    <type>other</type>
    <title/>
    <reference>https://example.com</reference>
    <description/>
    <url/>
  </reference>
  <reference>
    <type>other</type>
    <title/>
    <reference>327</reference>
    <description/>
    <url/>
  </reference>
  <reference>
    <type>bugtraq</type>
    <title/>
    <reference>49778</reference>
    <description/>
    <url/>
  </reference>
  <reference>
    <type>cve</type>
    <title/>
    <reference>CVE-2011-3389</reference>
    <description/>
    <url/>
  </reference>
</references>

I have used xidel to play around with grabbing this, but have so far not managed to get it correct. The closest I have got is:

//references[1]/reference[1]/reference[normalize-space(text()='CVE')[1]

Which prints out every reference:

CWE:327
https://example.com
327
49778
CVE-2011-3389

Solution

  • This xpath gets the value as expected

    //reference[type[.="cve"]]/reference/text()

    xmllint --xpath '//reference[type[.="cve"]]/reference/text()' tmp2.xml 
    CVE-2011-3389