sed parse small xml file

I have a tmp.xml file like:

<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Ip>193.143.121.198</Ip>
  <Status>OK</Status>
  <CountryCode>PL</CountryCode>
  <CountryName>Poland</CountryName>
  <RegionCode>82</RegionCode>
  <RegionName>Pomorskie</RegionName>
  <City>Gdansk</City>
  <ZipPostalCode></ZipPostalCode>
  <Latitude>54.35</Latitude>
  <Longitude>18.6667</Longitude>
  <Timezone>0</Timezone>
  <Gmtoffset>0</Gmtoffset>
  <Dstoffset>0</Dstoffset>
</Response>

where I'm trying to search for specific fields like this:

cc=`grep CountryCode tmp.xml | tr -d '\t' | sed 's/^<.*>\([^<].*\)<.*>$/\1/' `
echo $cc
rn=`grep RegionName tmp.xml | tr -d '\t' | sed 's/^<.*>\([^<].*\)<.*>$/\1/' `
echo $rn
ct=`grep City tmp.xml | tr -d '\t' | sed 's/^<.*>\([^<].*\)<.*>$/\1/' `
echo $ct

which outputs

<CountryCode>PL</CountryCode>
<CountryName>Poland</CountryName>
<RegionName>Pomorskie</RegionName>
<City>Gdansk</City>

I want an ouput like:

PL
Poland
Pomorskie
Gdansk

what is wrong with my sed command and is there a better/more elegant way to do this?

Try:

awk -F"[<>]" '/CountryCode/||/CountryName/||/RegionName/||/City/{print $3}' file

Shorter :wink:

awk -F"[<>]" '/Country|RegionName|City/{print $3}' file

A sed version...

sed -n 's/^.*<\(CountryCode\|CountryName\|RegionName\|City\)>\([^<]*\)<\/.*$/\2/p

js.

you can try this :wink:

[root@rhnserver ~]# grep CountryCode xml | tr -d '\t' |  sed 's/\(.*\)>\(.*\)<\(.*\)/\2/'
PL
#!/bin/sh

[ "$1" ] && exec < "$1"

IFS='<>'
while read -r __ key value __; do
    case $key in 
        CountryCode|CountryName|RegionName|City) echo $value;;
    esac
done

If optional file argument is not provided, read from standard input.

Regards,
Alister

This one is most elegant, imho, hehe:

#!/bin/perl

use XML::Simple;

$xml = new XML::Simple;

$data = $xml->XMLin("tmp.xml");

print "$data->{CountryCode}\n$data->{CountryName}\n$data->{RegionName}\n$data->{City}\n";

Enjoy!

Using XMLStarlet

/usr/local/bin/xml sel -t -m "//Response" -v "CountryCode" -n -v "CountryName" -n -v "RegionName" -n -v "City" infile.xml

Thanks, I installed xmlstarlet and started to play with it, but couldn't find the right documentation to do what I wanted, it's probably a better way to do it though :slight_smile:

You can also use xsltproc. Here is a stylesheet which will do what you want.

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

   <xsl:output method="text"/>

   <xsl:template match="Response">
      <xsl:value-of select="CountryCode" />
      <xsl:text>
</xsl:text>
      <xsl:value-of select="CountryName" />
      <xsl:text>
</xsl:text>
      <xsl:value-of select="RegionName" />
      <xsl:text>
</xsl:text>
      <xsl:value-of select="City" />
      <xsl:text>
</xsl:text>
   </xsl:template>

</xsl:stylesheet>