Unable to associate or grouping each set of xml attributes in bash script

Viewed 83

I have following format xml which has multiple occurrences of same attributes ( name , code and format ).

<?xml version="1.0" encoding="UTF-8"?>
<config>
 <input>
    <pattern>
        <name>ABC</name>
        <code>1234</code>
        <format>txt</format>
    </pattern>
 </input>
 <input>
    <pattern>
        <name>XYZ</name>
        <code>7799</code>
        <format>csv</format>
     </pattern>
 </input>
</config>

I want to parse each of these patterns and construct string like : ABC-1234-txt , XYZ-7799-csv etc... and add this to an array. The idea here is to group each pattern by constructing the string which will further be used. I have tried below command but unable to maintain the grouping :

awk -F'</?name>|</?code>|</?format>' ' { print $2 } ' sample.xml

It simply prints available values of these attributes in xml. As I am not an expert in bash so can anyone please suggest me how to group each pattern in above mentioned format in string.

2 Answers

With bash and xmlstarlet:

mapfile -t array < <(
  xmlstarlet select \
    --text --template --match '//config/input/pattern' \
    --value-of "concat(name,'-',code,'-',format)" -n file.xml
)
declare -p array

Output:

declare -a array=([0]="ABC-1234-txt" [1]="XYZ-7799-csv")

See: help mapfile and xmlstarlet select

with xslt:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" omit-xml-declaration="yes" indent="no"/>
<xsl:strip-space  elements="*"/>
<xsl:template match="pattern">
    <xsl:value-of select="concat(name,'-',code,'-',format,'&#xA;')"/>
</xsl:template>
</xsl:stylesheet>

Apply the transform via xsltproc:

$ xsltproc example.xslt sample.xml
ABC-1234-txt
XYZ-7799-csv

Populate array with xslt output:

$ declare -a my_array 
$ my_array=($(xsltproc example.xslt sample.xml))
$ echo "${my_array[@]}"
ABC-1234-txt XYZ-7799-csv
$ echo "${my_array[1]}"
XYZ-7799-csv
Related