Search code examples
xmllinuxsoapxmlstarletxmllint

Extract data from XML file with similar Blocks


Source

<?xml version="1.0"?>
 <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Body>
      <lima2t:runlargeResponse xmlns:lima2t="uri://Metadata.com/home/1.0">
        <data>
          <capacity>
              <name>Everyday.Italian.Dish</name>
              <currency>($)</currency>
              <CashAmount>not.used.for.this.transaction</CashAmount>
              <CheckAmount>not.used.for.this.transaction</CheckAmount>
              <CreditAmount>not.used.for.this.transaction</CreditAmount>
          </capacity>
          <capacity>
              <name>Everyday.French.Dish</name>
              <currency>($)</currency>
              <CashAmount>not.used.for.this.transaction</CashAmount>
              <CheckAmount>not.used.for.this.transaction</CheckAmount>
              <CreditAmount>134,70</CreditAmount>
          </capacity>
      </data>
    </lima2t:runlargeResponse>
  </soap:Body>
</soap:Envelope>

Goal Extract:

134,70 from <CreditAmount>134,70</CreditAmount>

I tried this Command, but the command outputs everything on the screen

xmllint --path '//soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"/soap:Body/lima2t:runlargeResponse xmlns:lima2t="uri://Metadata.com/home/1.0"/data/capacity/@name="Everyday.French.Dish"/CreditAmount/text()' op.xml

I feel like something is missing but I can't find what


Solution

  • Like this:

    xmllint --xpath '
        //data/capacity[name="Everyday.French.Dish"]/CreditAmount/text()
    ' op.xml
    

    Or using shell switch (need extra post processing to remove garbage):

    xmllint --shell op.xml<<EOF
    cat //data/capacity[name="Everyday.French.Dish"]/CreditAmount/text()
    EOF
    

    Or using :

    xmlstarlet sel -t -v '
        //data/capacity[name="Everyday.French.Dish"]/CreditAmount/text()
    ' op.xml
    

    Output:

    134,70