2

The Problem> I have some xml returned from an API call stored in get_build_info.xml. I am trying to grab an attribute from that xml, build_id. Here is the xml:

 <?xml version="1.0" encoding="UTF-8"?>

<buildinfo xmlns:xsi="http&#x3a;&#x2f;&#x2f;www.w3.org&#x2f;2001&#x2f;XMLSchema-instance" xmlns="https&#x3a;&#x2f;&#x2f;analysiscenter.veracode.com&#x2f;schema&#x2f;4.0&#x2f;buildinfo" xsi:schemaLocation="https&#x3a;&#x2f;&#x2f;analysiscenter.veracode.com&#x2f;schema&#x2f;4.0&#x2f;buildinfo https&#x3a;&#x2f;&#x2f;analysiscenter.veracode.com&#x2f;resource&#x2f;4.0&#x2f;buildinfo.xsd" buildinfo_version="1.4" account_id="1234" app_id="010101" sandbox_id="020202" build_id="987654321"><build version="4 Sep 2020 Static &#x28;2&#x29;" build_id="987654321" submitter="Someone Else" platform="Not Specified" lifecycle_stage="Not Specified" results_ready="true" policy_name="Some Development App Policy" policy_version="7" policy_compliance_status="Conditional Pass" rules_status="Not Assessed" grace_period_expired="false" scan_overdue="false" legacy_scan_engine="false">
      <analysis_unit analysis_type="Static" published_date="2020-09-04T11&#x3a;44&#x3a;09-04&#x3a;00" published_date_sec="1599234249" status="Results Ready" engine_version="20200821190810"/>
   </build>
</buildinfo>

What I've tried> The following, and many other variations thereof:

xmllint --xpath 'string(//xml/buildinfo/@build_id)' get_build_info.xml

xmllint --xpath 'string(//buildinfo/@build_id)' get_build_info.xml

xmllint --xpath 'string(/xml/buildinfo/@build_id)' get_build_info.xml

xmllint --xpath '(//xml/buildinfo/build_id/text())' get_build_info.xml

xmllint --xpath '(/xml/buildinfo/build_id/text())' get_build_info.xml

The last two at least yield some kind of output, albeit be that "XPath set is empty". The first few where I'm using that 'string( +...+ @build_id in the --xpath, I just get nothing returned. These all appear to exit 0 from bash as well so there's no syntax issue from what I can tell. Like I said, I'm a n00b. I looked at other popular tickets on stackoverflow and that's what got me to this point. I might very well not be taking something obvious into account here, so assume that I know nothing about bash (which is close to true). I'm happy to be given a direction to go and find the answer myself.

new2tech
  • 53
  • 6
  • 1
    It is about the namespace, this is a useful read with solutions: https://stackoverflow.com/questions/8264134/xmllint-failing-to-properly-query-with-xpath/8266075#8266075 – thanasisp Sep 04 '20 at 19:47
  • Thank you! I'm checking the link out now, seems exactly what my issue is and what I need to read up on. – new2tech Sep 06 '20 at 02:16
  • If you're interested in an alternative, like [tag:xidel], you can do just: `xidel -s get_build_info.xml -e '//@build_id'`. – Reino Sep 07 '20 at 10:25
  • Will check that out too. Thanks – new2tech Sep 08 '20 at 13:51

1 Answers1

2

You're are getting entangled with namespaces, so try using an xpath expression like:

//*[local-name()='buildinfo']/@build_id

and see if it works.

Jack Fleeting
  • 24,385
  • 6
  • 23
  • 45
  • !! This returned the value I needed and a little bit extra -```build_id="987654321"``` . That's fantastic progress. I'm assuming there is some nifty way to pull the actual value out of that as well. Will be looking into that, any suggestions are appreciated! – new2tech Sep 06 '20 at 03:28
  • 1
    @new2tech It should not do that - but try putting `string()` around the whole thing. Also - more generally, consider using something like xmlstarlet, or - more advanced - xidel. – Jack Fleeting Sep 06 '20 at 11:31
  • string() around the whole --xpath expression? I've tried a few different options but I think I'm not getting the right spot in the xpath for this: ```xmllint --xpath string("//*[local-name()='buildinfo']/@build_id")``` ```xmllint --xpath "string(//*[local-name()='buildinfo']/@build_id)"``` Due to limitiations with which dependencies can be installed, xmllint may be the only tool for this situation, but I will look into the other suggestions. Thanks you! – new2tech Sep 07 '20 at 01:35
  • Oh wait - I got it! it was ```xmllint --xpath "string(//*[local-name()='buildinfo']/@build_id)" get_build_info.xml``` That looks like the exact same command (#2) that I listed in my above comment.. not sure what I did wrong but It's there and assigned to a variable!! Thank you! – new2tech Sep 07 '20 at 01:57
  • Turns out there were some weird syntax errors when I tabbed-completed the get_build_info.xml. That was my problem. – new2tech Sep 07 '20 at 02:00
  • Done. Apparently I can't upvote your answer, but it is now the solution :) – new2tech Sep 08 '20 at 13:50