Home > Back-end >  Extract XML with xmllint
Extract XML with xmllint

Time:09-17

I am very, very, very confused with xmllint. Are there better alternatives? Is there a better way to learn about it than the man page?

How come these two commands work separately, but fail when I combine them?

xmllint --format test.txt --xpath "//*[name()='model']/@mh | //*[name()='instance']/@value" | sed -E -e 's/\s /\n/g'
xmllint --format test.txt --xpath '//*[@id="0x1006e"]/text()'

Combined:

xmllint --format /opt/spectrum/custom/test.txt --xpath "//*[name()='model']/@mh | '//*[@id="0x1006e"]/text()' | //*[name()='instance']/@value" | sed -E -e 's/\s /\n/g'

I also understand it is frowned upon to use sed with XML, but the format option does not work at all when I extract info. XML is really confusing me.

My ultimate goal is to go from this:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model-response-list xmlns="http://null" total-models="1" throttle="1" error="EndOfResults">
  <model-responses>
    <model mh="NULL1">
      <attribute id="0x1006e">NULL2</attribute>
      <attribute-list id="NULL3">
        <instance oid="1" value="Vlan1"/>
        <instance oid="10001" value="FastEthernet1/0/1"/>
        <instance oid="10002" value="FastEthernet1/0/2"/>
        <instance oid="10003" value="FastEthernet1/0/3"/>
        <instance oid="10004" value="FastEthernet1/0/4"/>
        <instance oid="10005" value="FastEthernet1/0/5"/>
        <instance oid="10006" value="FastEthernet1/0/6"/>
        <instance oid="10007" value="FastEthernet1/0/7"/>
        <instance oid="10008" value="FastEthernet1/0/8"/>
      </attribute-list>
    </model>
  </model-responses>
</model-response-list>

to this:

mh="NULL1"
NULL2
Vlan1
FastEthernet1/0/1
FastEthernet1/0/2
FastEthernet1/0/3
FastEthernet1/0/4
FastEthernet1/0/5
FastEthernet1/0/6
FastEthernet1/0/7
FastEthernet1/0/8

Please help me to XML :'(

CodePudding user response:

There's mixed quoting on the combined XPath expression. Fixing it makes the command work

xmllint --format tmp.xml --xpath "//*[name()='model']/@mh | //*[@id='0x1006e']/text() | //*[name()='instance']/@value" | sed -E -e 's/\s /\n/g'

Result

mh="NULL1"
NULL2

value="Vlan1"

value="FastEthernet1/0/1"

value="FastEthernet1/0/2"

value="FastEthernet1/0/3"

value="FastEthernet1/0/4"

value="FastEthernet1/0/5"

value="FastEthernet1/0/6"

value="FastEthernet1/0/7"

value="FastEthernet1/0/8"

CodePudding user response:

A different approach might be to use an xslt transform to generate the output you are seeking:

xslt file:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" />
  <xsl:strip-space elements="*"/>
  <xsl:template match="/">
    <xsl:apply-templates select="//@mh" />
    <xsl:apply-templates match="attribute" />
    <xsl:text>&#xa;</xsl:text>
    <xsl:apply-templates select="//@value" />
  </xsl:template>

  <xsl:template match="@mh">
    <xsl:value-of select="concat('mh=&quot;', ., '&quot; &#xA;')"/>
  </xsl:template>
  <xsl:template match="@value">
    <xsl:value-of select="concat(., '&#xA;')"/>
  </xsl:template>

</xsl:stylesheet>

xml file:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model-response-list xmlns="http://null" total-models="1" throttle="1" error="EndOfResults">
  <model-responses>
    <model mh="NULL1">
      <attribute id="0x1006e">NULL2</attribute>
      <attribute-list id="NULL3">
        <instance oid="1" value="Vlan1"/>
        <instance oid="10001" value="FastEthernet1/0/1"/>
        <instance oid="10002" value="FastEthernet1/0/2"/>
        <instance oid="10003" value="FastEthernet1/0/3"/>
        <instance oid="10004" value="FastEthernet1/0/4"/>
        <instance oid="10005" value="FastEthernet1/0/5"/>
        <instance oid="10006" value="FastEthernet1/0/6"/>
        <instance oid="10007" value="FastEthernet1/0/7"/>
        <instance oid="10008" value="FastEthernet1/0/8"/>
      </attribute-list>
    </model>
  </model-responses>
</model-response-list>

Output from transform:

$ xsltproc sample.xslt sample.xml 
mh="NULL1" 
NULL2
Vlan1
FastEthernet1/0/1
FastEthernet1/0/2
FastEthernet1/0/3
FastEthernet1/0/4
FastEthernet1/0/5
FastEthernet1/0/6
FastEthernet1/0/7
FastEthernet1/0/8
  • Related