Using Raku (formerly known as Perl_6):
I recognize the OP requested a bash
script, but since other answers have deviated from this requirement, here's a Raku solution (4 one-liners):
raku -MXML -e 'my $xml=open-xml($*ARGFILES.Str); $xml.elementslookfor(:TAG<host>, :RECURSE(Inf) ).>>.cdata>>.data.put;' raku -MXML -e 'my $xml=open-xml($*ARGFILES.Str); $xml.elementslookfor(:TAG<username>, :RECURSE(Inf) ).>>.cdata>>.data.put;' raku -MXML -e 'my $xml=open-xml($*ARGFILES.Str); $xml.elementslookfor(:TAG<password>, :RECURSE(Inf) ).>>.cdata>>.data.put;' raku -MXML -e 'my $xml=open-xml($*ARGFILES.Str); $xml.elementslookfor(:TAG<dbname>, :RECURSE(Inf) ).>>.cdata>>.data.put;'
OUTPUT:
localhost root pass123 testdb
Briefly, Raku is called at the bash command line, and -M
module XML
is loaded with the command -MXML
. The xml file is opened with open-xml
and stored in the $xml
object. Then the $xml
object is queried recursively for desired tags [ in point of fact, andthe lookfor(...)
code is a shortcut for elements(..., :RECURSE)
]. Then the CDATA
values are extracted.
There are other ways to get the desired data, such as simply walking the XML
-parse tree:
raku -MXML -e 'my $xml=open-xml($*ARGFILES.Str); .cdata.map(*.data).put for $xml.nodes[1].nodes[7].nodes[3].nodes[1].nodes[1,3,5,7];'
Which can be simplified to:
raku -MXML -e 'my $xml=open-xml($*ARGFILES.Str); .cdata>>.data.put for $xml.nodes[1][7][3][1][1,3,5,7];'
The two lines of code above each return:
localhost root pass123 testdb
https://github.com/raku-community-modules/XML
https://raku.org/
[For alternative solutions in Raku, there's also the LibXML
module, which provides bindings to the (possibly faster) libxml2
library. See https://modules.raku.org/dist/LibXML:cpan:WARRINGD].