How to extract device ID's into an array from API users/name XML output?

Malcolm
Contributor II

So I am currently working on some API extension attribute based scripts, for use with extension attributes.

I have a script working that will do the following:

  • List the assigned number of Computers to a user and List it as a number, under a computer device as a extension attribute
  • List the assigned number of mobile devices to a user and List it as a number, under a computer device as a extension attribute

 

 

 

# get the number of mobile devices assigned to the user
UserXML=$( /usr/bin/curl \
--header "accept: application/xml" \
--request GET \
--silent \
--header "Authorization: Bearer $token" \
--url "$jamfProURL/JSSResource/users/name/$strassigneduser")
#echo "xml results $UserXML"
mobileDevicesCount=$(echo $UserXML | grep -o "<mobile_devices>" | wc -l)
# get the number of mobile devices assigned to the user
UserXML=$( /usr/bin/curl \
--header "accept: application/xml" \
--request GET \
--silent \
--header "Authorization: Bearer $token" \
--url "$jamfProURL/JSSResource/users/name/$strassigneduser")
#echo "xml results $UserXML"

computerDevicesCount=$(echo $UserXML | grep -o "<computer>" | wc -l)

 

 

 

 

These features will help our general operations, but will also allow us to create smart groups from, to identify when a user has both an iPad and a MacBook.

However I want to now add additional code to extract more data. But having some difficulty.

I am now looking at attempting to now export the device ID's from the XML as an array, from the get Users by name API, so that I can leverage the device ID's in a way to:

  • list hyper links to the various devices
  • exclude unmanaged devices from the results

All my attempts to strip the data into an array of device ID's has been unsuccessful.

Unless there is of course an easier way to do this?

 

1 ACCEPTED SOLUTION

Oops, my bad. The xml lint command needs an extra - at the end to tell it to read from stdin. Sorry about that. Must have missed it when I copied from my terminal the other day. I'm on mobile currently, so I haven't tested this yet, but it should look like this. 

ID_ARRAY=($(echo $UserXML | xmllint --xpath '//mobile_devices//id/text()' -))

View solution in original post

4 REPLIES 4

TrentO
Contributor II

The tool you are looking for is xmllint. It's built into macOS and allows you to run arbitrary xpath queries against xml data. For example, given your $UserXML variable you could write

ID_ARRAY=($(echo $UserXML | xmllint --xpath '//mobile_devices//id/text()'))

 

Malcolm
Contributor II

Thanks @TrentO , xmllint was what I was dabbing as a method, but I was getting errors with your example I am getting: Running as #!/bin/zsh

Usage : xmllint [options] XMLfiles ... Parse the XML files and output the result of the parsing --version : display the version of the XML library used --debug : dump a debug tree of the in-memory document --shell : run a navigating shell --debugent : debug the entities defined in the document --copy : used to test the internal copy implementation --recover : output what was parsable on broken XML documents --huge : remove any internal arbitrary parser limits --noent : substitute entity references by their value --noenc : ignore any encoding specified inside the document --noout : don't output the result tree --path 'paths': provide a set of paths for resources --load-trace : print trace of all external entities loaded --nonet : refuse to fetch DTDs or entities over network --nocompact : do not generate compact text nodes --htmlout : output results as HTML --nowrap : do not put HTML doc wrapper --valid : validate the document in addition to std well-formed check --postvalid : do a posteriori validation, i.e after parsing --dtdvalid URL : do a posteriori validation against a given DTD --dtdvalidfpi FPI : same but name the DTD with a Public Identifier --quiet : be quiet when succeeded --timing : print some timings --output file or -o file: save to a given file --repeat : repeat 100 times, for timing or profiling --insert : ad-hoc test for valid insertions --compress : turn on gzip compression of output --html : use the HTML parser --xmlout : force to use the XML serializer when using --html --nodefdtd : do not default HTML doctype --push : use the push mode of the parser --pushsmall : use the push mode of the parser using tiny increments --push-structured-error-fatal-stop : call xmlStopParser() on fatal structured errors --memory : parse from memory --maxmem nbbytes : limits memory allocation to nbbytes bytes --nowarning : do not emit warnings from parser/validator --noblanks : drop (ignorable?) blanks spaces --nocdata : replace cdata section with text nodes --format : reformat/reindent the output --encode encoding : output in the given encoding --dropdtd : remove the DOCTYPE of the input docs --pretty STYLE : pretty-print in a particular style 0 Do not pretty print 1 Format the XML content, as --format 2 Add whitespace inside tags, preserving content --c14n : save in W3C canonical format v1.0 (with comments) --c14n11 : save in W3C canonical format v1.1 (with comments) --exc-c14n : save in W3C exclusive canonical format (with comments) --nsclean : remove redundant namespace declarations --testIO : test user I/O support --catalogs : use SGML catalogs from $SGML_CATALOG_FILES otherwise XML Catalogs starting from file:///etc/xml/catalog are activated by default --nocatalogs: deactivate all catalogs --auto : generate a small doc on the fly --xinclude : do XInclude processing --noxincludenode : same but do not generate XInclude nodes --nofixup-base-uris : do not fixup xml:base uris --loaddtd : fetch external DTD --dtdattr : loaddtd + populate the tree with inherited attributes --stream : use the streaming interface to process very large files --walker : create a reader and walk though the resulting doc --pattern pattern_value : test the pattern support --chkregister : verify the node registration code --relaxng schema : do RelaxNG validation against the schema --schema schema : do validation against the WXS schema --schematron schema : do validation against a schematron --sax1: use the old SAX1 interfaces for processing --sax: do not build a tree but work just at the SAX level --sax-fatal-stop: call xmlStopParser() on fatal errors during SAX parsing --oldxml10: use XML-1.0 parsing rules before the 5th edition --xpath expr: evaluate the XPath expression, imply --noout Libxml project home page: https://gitlab.gnome.org/GNOME/libxml2 ID_ARRAY

Oops, my bad. The xml lint command needs an extra - at the end to tell it to read from stdin. Sorry about that. Must have missed it when I copied from my terminal the other day. I'm on mobile currently, so I haven't tested this yet, but it should look like this. 

ID_ARRAY=($(echo $UserXML | xmllint --xpath '//mobile_devices//id/text()' -))

Malcolm
Contributor II

Thanks very much, this seems like it worked, I've been trying to get bard api to generate the correct code with xmllint, but it was always getting it wrong.