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
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
[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
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>