I have a complex structured XML file from which I'm trying to parse some values, using xmlstartlet. I think the issue is that the logical objects are identified by element attributes and not the actual element names.
The file test.xml, simplified for this example, looks like this:
<?xml version="1.0" encoding="utf-8"?>
<configDump>
<cluster top-level-assembly="XYZ12312312312">
</cluster>
<views>
<view status="ok" name="ABC">
<viewInitiators>
<viewInitiator id="ABCi1"></viewInitiator>
<viewInitiator id="ABCi2"></viewInitiator>
</viewInitiators>
<viewPorts>
<viewPort id="ABCp1"></viewPort>
<viewPort id="ABCp2"></viewPort>
</viewPorts>
<viewVolumes>
<viewVolume lun="1" id="ABCv1"></viewVolume>
<viewVolume lun="2" id="ABCv2"></viewVolume>
</viewVolumes>
</view>
<view status="ok" name="DEF">
<viewInitiators>
<viewInitiator id="DEFi1"></viewInitiator>
<viewInitiator id="DEFi2"></viewInitiator>
</viewInitiators>
<viewPorts>
<viewPort id="DEFp1"></viewPort>
<viewPort id="DEFp2"></viewPort>
</viewPorts>
<viewVolumes>
<viewVolume lun="1" id="DEFv1"></viewVolume>
<viewVolume lun="2" id="DEFv2"></viewVolume>
</viewVolumes>
</view>
</views>
</configDump>
I'm trying to generate output with fields that look like:
<top-level-assembly>-<view-name>,<viewInitiator-ID>
When I run the following:
xmlstarlet sel -t \
-m //cluster \
--var sn=@top-level-assembly \
-m //views/view \
--var view=@name \
-m //views/view/viewInitiators/viewInitiator \
-v 'concat($sn,"-",$view,",",@id)' -n test.xml
I get the following output:
XYZ12312312312-ABC,ABCi1
XYZ12312312312-ABC,ABCi2
XYZ12312312312-ABC,DEFi1
XYZ12312312312-ABC,DEFi2
XYZ12312312312-DEF,ABCi1
XYZ12312312312-DEF,ABCi2
XYZ12312312312-DEF,DEFi1
XYZ12312312312-DEF,DEFi2
As you can seem I am getting all the "initiator" values under each "view", and not just the ones that are in that structure in the XML. I was expecting and hoping to get just:
XYZ12312312312-ABC,ABCi1
XYZ12312312312-ABC,ABCi2
XYZ12312312312-DEF,DEFi1
XYZ12312312312-DEF,DEFi2
Any thoughts on what I'm doing wrong?
CodePudding user response:
Any thoughts on what I'm doing wrong?
The -m
options nest - to xsl:for-each
statements - so you're asking for all viewInitiator/@id
s for each view
. To see the generated XSLT code add a -C
option before -t
.
The desired output can be generated by:
xmlstarlet sel -t \
--var sn='configDump/cluster/@top-level-assembly' \
-m '//viewInitiator' \
-v 'concat($sn,"-",../../@name,",",@id)' -n \
< file.xml