Adapting one of the examples from the xmlstarlet docs:
xmlstarlet sel -T -t -m '//*' \ -i '@display' \ -m 'ancestor-or-self::*' \ -i '(position()=last())' \ -o '-> ' -v '@display' -b \ -o $'\t' -b \ -n foo.xml
The example is:
Print structure of XML element using xml sel (advanced XPath expressions and xml sel command usage)
xml sel -T -t -m '//*' \-m 'ancestor-or-self::*' -v 'name()' -i 'not(position()=last())' -o . -b -b -n \xml/structure.xml
Result Output:
a1a1.a11a1.a11.a111a1.a11.a111.a1111a1.a11.a112a1.a11.a112.a1121a1.a12a1.a13a1.a13.a131
From here, the things we need to modify are:
- print the
display
attribute instead of thename
, so@display
instead ofname()
- print it only for the last element. We already have the test for printing
.
for all but the last element, so it's easy to invert that. - print tabs to indent (we can do it after every element, it will just leave trailing, invisible tab), so just
-o $'\t'
.$'\t'
in bash will get you a tab character. - print only for elements which have the
display
attribute, so-i '@display'
I have indented the command above to make the flow clearer.
The output I get:
$ xmlstarlet sel -T -t -m '//*' -i '@display' -m 'ancestor-or-self::*' -i '(position()=last())' -o '-> ' -v '@display' -b -o $'\t' -b -n foo.xml-> English -> Main Menu -> Broadband -> Load and Save Profiles -> Load Profile -> Save Profile -> Delete Profile -> Interface -> xDSL -> SFP -> Ethernet -> SHDSL -> xDSL Interface -> xDSL Mode -> Annex A/M -> Annex B/J -> MAC Address -> MAC Address -> Vectoring Mode -> Disabled -> Enabled -> Friendly -> G.FAST -> Disabled -> Enabled
After thinking a bit, the following is simpler:
xmlstarlet sel -T -t -m '//*' \ -i '@display' \ -m 'ancestor::*' \ -o $'\t' -b \ -o '-> ' -v '@display' -n foo.xml
Using ancestor::*
instead of ancestor-or-self::*
makes printing the tabs correctly easier, and eliminates the extra test for last element.
Similar output, but without trailing tabs:
-> English -> Main Menu -> Broadband -> Load and Save Profiles -> Load Profile -> Save Profile -> Delete Profile -> Interface -> xDSL -> SFP -> Ethernet -> SHDSL -> xDSL Interface -> xDSL Mode -> Annex A/M -> Annex B/J -> MAC Address -> MAC Address -> Vectoring Mode -> Disabled -> Enabled -> Friendly -> G.FAST -> Disabled -> Enabled