Search code examples
xmlxpathxml-parsingxmlstarletxmllint

Getting values by using xmlstarlet or xmllint with libxml version 20706


Here is the part of my xml;

          <LOGICAL_DRIVE>
                <LABEL VALUE = "01"/>
                <STATUS VALUE = "Degraded"/>
                <CAPACITY VALUE = "99 GiB"/>
                <FAULT_TOLERANCE VALUE = "RAID 1/RAID 1+0"/>
                <LOGICAL_DRIVE_TYPE VALUE = "Data LUN"/>
                <ENCRYPTION_STATUS VALUE = "Not Encrypted"/>
                <PHYSICAL_DRIVE>
                     <LABEL VALUE = "Port 1I Box 1 Bay 1"/>
                     <STATUS VALUE = "OK"/>
                     <MODEL VALUE = "MM1000GBKAL"/>
                     <CAPACITY VALUE = "931 GiB"/>
                     <MARKETING_CAPACITY VALUE = "1000 GB"/>
                     <LOCATION VALUE = "Port 1I Box 1 Bay 1"/>
                     <FW_VERSION VALUE = "HPGE"/>
                     <DRIVE_CONFIGURATION VALUE = "Configured"/>
                     <ENCRYPTION_STATUS VALUE = "Not Encrypted"/>
                     <MEDIA_TYPE VALUE = "HDD"/>
                </PHYSICAL_DRIVE>
                <PHYSICAL_DRIVE>
                     <LABEL VALUE = "Port 2I Box 1 Bay 5"/>
                     <STATUS VALUE = "FAILED"/>
                     <MODEL VALUE = "MM1000GBKAL"/>
                     <CAPACITY VALUE = "931 GiB"/>
                     <MARKETING_CAPACITY VALUE = "1000 GB"/>
                     <LOCATION VALUE = "Port 2I Box 1 Bay 5"/>
                     <FW_VERSION VALUE = "HPGE"/>
                     <DRIVE_CONFIGURATION VALUE = "Configured"/>
                     <ENCRYPTION_STATUS VALUE = "Not Encrypted"/>
                     <MEDIA_TYPE VALUE = "HDD"/>
                </PHYSICAL_DRIVE>
           </LOGICAL_DRIVE>
           <LOGICAL_DRIVE>

I would like to get the VALUE of the LABEL where the VALUE of the STATUS of LOGICAL_DRIVE is not OK.

I was using the following;

xmllint --xpath "//LOGICAL_DRIVE[.//STATUS[not(@VALUE='OK')]]/LABEL[@VALUE]" health.xml

However, I have a system with older version and I can not update it. I have tried this;

xmlstarlet sel -t -m "//PHYSICAL_DRIVE/STATUS/@value='OK']" -v "../LABEL/text()" -nl health.xml

But it didn't work. In this version of xml, how can I get the VALUE of the LABEL where the VALUE of the STATUS of LOGICAL_DRIVE is not OK?

Thanks in advance


Solution

  • Here's an xmlstarlet command that should work:

    xmlstarlet sel -T -t -m "//PHYSICAL_DRIVE[not(STATUS/@VALUE='OK')]/LABEL" -v "@VALUE" -nl health.xml