Shell script for XML code parsing.

I need to create a shell script that can parse the below XML and send a string back adding all XML values. The text which's not in angular braces are to be printed.

Sample code:

<RequestBillsRsp version="1.0"><BillSummaryData><AgreementNumberFull>13-WY-8425-2</AgreementNumberFull><AgreementNumberAbbr>WY84252</AgreementNumberAbbr><LineOfBusiness>F</LineOfBusiness><CompanyCode>0005</CompanyCode><UniqDigit/><StateCode/><UnitID>13</UnitID><DueDate>04/12/2012</DueDate><BillAmount>282.00</BillAmount><StateAgentCode>131533</StateAgentCode><AgentName>DAN CUTHBERT</AgentName><AgentPhoneNumber>(847)228-6620</AgentPhoneNumber><PayableFlag>N</PayableFlag><ACHPayableFlag>N</ACHPayableFlag><BillROCode>01</BillROCode><PayableMessage>001</PayableMessage><BillDate>20090824</BillDate><SeqNum>0615882</SeqNum><PlcyDispName>PRIOVOLOS, TASOS & SOFIA</PlcyDispName><MailingZipcode/><RiskDesc>18214 S SPRING MEADOWS DR</RiskDesc><AnyAmountPayableFlag>N</AnyAmountPayableFlag><ACHAnyAmountPayableFlag>N</ACHAnyAmountPayableFlag></BillSummaryData><AddressInfo><AddressOne/><AddressTwo/><City/><State/><Zip/></AddressInfo><PayerName/><messages rc="00"/></RequestBillsRsp>

Sample o/p:

13-WY-8425-2
DAN CUTHBERT
(847)228-6620
PRIOVOLOS, TASOS & SOFIA
18214 S SPRING MEADOWS DR
N

Try this
Assumption, these data will be found in these columns always

 awk -F'<|>' '{print $7,$43,$47,$71,$81,$85}' OFS="\n" infile

If you think the xml format is different, you can enhance this code for the remaining fields

awk -F'<|>' '{ for(i=0;i<NF;i++){ if($i=="AgreementNumberFull"){print $++i} } }' infile

regards,
Ahamed

Hey Ahamed,

Thanks for ur time but ur script wud work perfectly fne if the code is provided in a single line but the XML file can have the code even in the paragraph form. So if u can suggest some other alternative.

Yuo gave the input like that and so I coded it that way.

Assuming your xml file is in the format

<RequestBillsRsp version="1.0">
<BillSummaryData>
<AgreementNumberFull>13-WY-8425-2</AgreementNumberFull>
<AgreementNumberAbbr>WY84252</AgreementNumberAbbr>
<LineOfBusiness>F</LineOfBusiness>
<CompanyCode>0005</CompanyCode>
<UniqDigit/>
<StateCode/>
<UnitID>13</UnitID>
<DueDate>04/12/2012</DueDate>
<BillAmount>282.00</BillAmount>
...
awk -F'<|>' '$2~/AgreementNumberFull|AgentName|AgentPhoneNumber|PlcyDispName|RiskDesc|^AnyAmountPayableFlag/{print $3}' infile

regards,
Ahamed

if this helps :

sed "s/<[^>]*>/#/g;s/##*/\n/g" infile.xml
$ sed "s/<[^>]*>/#/g;s/##*/\n/g" tst.xml

13-WY-8425-2
WY84252
F
0005
13
04/12/2012
282.00
131533
DAN CUTHBERT
(847)228-6620
N
N
01
001
20090824
0615882
PRIOVOLOS, TASOS & SOFIA
18214 S SPRING MEADOWS DR
N
N

$

Before further selections (if you want to pipe it into the awk statement suggested by ahmed in #4), you can also :

sed "s/></>\n</g" tst.xml
# sed "s/></>\n</g" tst.xml
<RequestBillsRsp version="1.0">
<BillSummaryData>
<AgreementNumberFull>13-WY-8425-2</AgreementNumberFull>
<AgreementNumberAbbr>WY84252</AgreementNumberAbbr>
<LineOfBusiness>F</LineOfBusiness>
<CompanyCode>0005</CompanyCode>
<UniqDigit/>
<StateCode/>
<UnitID>13</UnitID>
<DueDate>04/12/2012</DueDate>
<BillAmount>282.00</BillAmount>
<StateAgentCode>131533</StateAgentCode>
<AgentName>DAN CUTHBERT</AgentName>
<AgentPhoneNumber>(847)228-6620</AgentPhoneNumber>
<PayableFlag>N</PayableFlag>
<ACHPayableFlag>N</ACHPayableFlag>
<BillROCode>01</BillROCode>
<PayableMessage>001</PayableMessage>
<BillDate>20090824</BillDate>
<SeqNum>0615882</SeqNum>
<PlcyDispName>PRIOVOLOS, TASOS & SOFIA</PlcyDispName>
<MailingZipcode/>
<RiskDesc>18214 S SPRING MEADOWS DR</RiskDesc>
<AnyAmountPayableFlag>N</AnyAmountPayableFlag>
<ACHAnyAmountPayableFlag>N</ACHAnyAmountPayableFlag>
</BillSummaryData>
<AddressInfo>
<AddressOne/>
<AddressTwo/>
<City/>
<State/>
<Zip/>
</AddressInfo>
<PayerName/>
<messages rc="00"/>
</RequestBillsRsp>
#

Here is an XSL stylesheet which does what you specified in your first post. In addition it does not output output newlines for empty elements.

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

<xsl:output method="text"/>

<xsl:template match="/">
     <xsl:apply-templates/>
</xsl:template>

<xsl:template match="node()">
   <xsl:if test="string(.)">
      <xsl:copy>
          <xsl:apply-templates select="node()"/><xsl:text>
</xsl:text>
      </xsl:copy>
   </xsl:if>
</xsl:template>

</xsl:stylesheet>
13-WY-8425-2
WY84252
F
0005
13
04/12/2012
282.00
131533
DAN CUTHBERT
(847)228-6620
N
N
01
001
20090824
0615882
PRIOVOLOS, TASOS & SOFIA
18214 S SPRING MEADOWS DR
N
N

Hey murphy...thanks for the XSL sheet. This XSL stylesheet does the same thing but i need to run these scripts on some servers so they need to be Shell. But cz of ur post i gotta knw few more things about XML and XSL. Thanks fr ur time :slight_smile:

---------- Post updated at 08:46 AM ---------- Previous update was at 08:26 AM ----------

@ctsgnb...ur code really worked but i'm not getting the output in new lines...everything is being displayed horizontally in a single line.

---------- Post updated at 08:51 AM ---------- Previous update was at 08:46 AM ----------

@ ahamed....accept my mistake. Did u try this code that u posted last? I tried it..got no output :frowning:

---------- Post updated at 03:17 PM ---------- Previous update was at 08:51 AM ----------

@ctsgnb:

# sed "s/<[^>]*>/#/g;s/##*/\n/g" tst.xml

n13-WY-8425-2nWY84252nFn0005n13n04/12/2012n282.00n131533nDAN CUTHBERTn(847)228-6620nNnNn01n001n20090824n0615882nPRIOVOLOS, TASOS & SOFIAn18214 S SPRING MEADOWS DRnNnNn

look at these "n"....tried hard but cud'nt locate the reason for these and also the o/p's in a single line...m using sun 5.10..

You haven't prevented shell interpolation with single quotes => \n is substituted on the way into the sed command by the shell.
either single quote the sed command string if you don't need shell interpolation

sed 's/<[^>]*>/#/g;s/##*/\n/g'

or double escape if you do

sed "s/<[^>]*>/#/g;s/##*/\\n/g"
sed "s/<[^>]*>/#/g;s/##*/#/g" tst.xml | tr '#' '\n' | paste -sd " "

xsltproc is available on nearly every server