munjalm has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks, I have an XML like below. I need to fetch only values Agreement ID, Cycle Code and Subscriber ID List values. However agreement id and cycle code contains always single values but subscriber id list can contain multiple values as in the snippet below. Kindly please help.
<PerformanceIndicator type="VEL Allowance pooling occurrence recurring + rolling restricted period sensitive with bundling" version="00000000 +0"> <Attribute name="Item ID" basicType="Numeric"><Value value="23409056"/ +></Attribute> <Attribute name="Agreement ID" basicType="Numeric"><Value value="15827 +134"/></Attribute> <Attribute name="Cycle code" basicType="Numeric"><Value value="1301"/> +</Attribute> <Attribute name="Cycle year" basicType="Numeric"><Value value="2015"/> +</Attribute> <Attribute name="Cycle month" basicType="Numeric"><Value value="2"/></ +Attribute> <Attribute name="Customer ID" basicType="Numeric"><Value value="164922 +51"/></Attribute> <Attribute name="PI type ID" basicType="Numeric"><Value value="9436004 +9"/></Attribute> <Attribute name="Offer instance" basicType="Numeric"><Value value="140 +546178"/></Attribute> <Attribute name="Rerate type" basicType="String"><Value value="R"/></A +ttribute> <Attribute name="Last event date" basicType="DateTime"><Value value="2 +015-02-25 19:34:41"/></Attribute> <Attribute name="Offer ID" basicType="Numeric"><Value value="23408986" +/></Attribute> <Attribute name="Expiration date" basicType="DateTime"><Value value="2 +015-02-28 23:59:59"/></Attribute> <Attribute name="PI status" basicType="Numeric"><Value value="4"/></At +tribute> <Attribute name="Billing arrangement" basicType="Numeric"><Value value +="0"/></Attribute> <Attribute name="Pay channel" basicType="Numeric"><Value value="0"/></ +Attribute> <Attribute name="Dummy string" basicType="String"><Value value="0"/></ +Attribute> <Attribute name="Dummy numeric" basicType="Numeric"><Value value="0"/> +</Attribute> <Attribute name="Dummy date" basicType="DateTime"><Value value="2020-1 +2-31 19:50:00"/></Attribute> <Attribute name="Dummy boolean" basicType="Boolean"><Value value="Yes" +/></Attribute> <Attribute name="Proration factor" basicType="Numeric"><Value value="1 +.0000"/></Attribute> <Attribute name="Quota per period" basicType="Numeric"><Value value="7 +500.00"><DimensionKey dimensionName="Period" index="0" value="0" nam +e=""/></Value></Attribute> <Attribute name="Rolled from previous cycle per period" basicType="Num +eric"><Value value=""/></Attribute> <Attribute name="Remaining quota per month and period" basicType="Nume +ric"><Value value="7344.0000"><DimensionKey dimensionName="Month" in +dex="0" value="0" name=""/><DimensionK ey dimensionName="Period" index="0" value="0" name=""/></Value></Attr +ibute> <Attribute name="Utilized quota per month and period" basicType="Numer +ic"><Value value="156.0000"><DimensionKey dimensionName="Month" inde +x="0" value="0" name=""/><DimensionKey dimensionName="Period" index="0" value="0" name=""/></Value></Attrib +ute> <Attribute name="Remaining quota to be rolled" basicType="Numeric"><Va +lue value=""/></Attribute> <Attribute name="Number of rolled cycles" basicType="Numeric"><Value v +alue="0"/></Attribute> <Attribute name="Full quota per period" basicType="Numeric"><Value val +ue="7500"><DimensionKey dimensionName="Period" index="0" value="0" n +ame=""/></Value></Attribute> <Attribute name="Limit quota" basicType="Numeric"><Value value="-1"><D +imensionKey dimensionName="Index" index="0" value="0" name=""/></Val +ue><Value value="-1"><DimensionKey di mensionName="Index" index="1" value="1" name=""/></Value></Attribute> <Attribute name="Remaining quota per subscriber" basicType="Numeric">< +Value value="-1"><DimensionKey dimensionName="Index" index="0" value +="0" name=""/></Value><Value value="-1 "><DimensionKey dimensionName="Index" index="1" value="1" name=""/></ +Value></Attribute> <Attribute name="Utilized quota per subscriber" basicType="Numeric"><V +alue value="0"><DimensionKey dimensionName="Index" index="0" value=" +0" name=""/></Value><Value value="0">< DimensionKey dimensionName="Index" index="1" value="1" name=""/></Val +ue></Attribute> <Attribute name="Subscriber ID list" basicType="Numeric"><Value value= +"15846291"><DimensionKey dimensionName="Index" index="0" value="0" n +ame=""/></Value><Value value="15613501 "><DimensionKey dimensionName="Index" index="1" value="1" name=""/></ +Value></Attribute> </PerformanceIndicator>

Replies are listed 'Best First'.
Re: XML Parsing
by Anonymous Monk on Feb 26, 2015 at 14:54 UTC
Re: XML Parsing
by karlgoethebier (Abbot) on Feb 26, 2015 at 15:53 UTC

    I got some ideas but i think your XML isn't valid.

    Update: Please try Validome or something similar...

    Best regards, Karl

    «The Crux of the Biscuit is the Apostrophe»

Re: XML Parsing
by graff (Chancellor) on Feb 27, 2015 at 05:54 UTC
    The problem with the OP XML sample is that, even when viewed/saved via the "download" link (to eliminate the PM line-wrapping), there is still other line wrapping that needs to be undone on several long lines near the end of the file.

    Once that's fixed, a simple bit of work with XPath expressions will get you what you want. I posted some sample code for this a while back, here: Re: XPath command line utility....

    If you want to try the script posted there, save it as "exp" somewhere in one of your PATH directories, make it executable, and run a command line like this:

    exp -p '//Attribute[@name="Agreement ID"]/Value/@value | //Attribute[@name="Cycle code"]/Value/@value | //Attribute[@name="Subscriber ID list"]/Value/@value' your_file.xml
    (NB: I'm using a bash shell, where it's best to use single-quotes on the outside and double-quotes inside.) When I ran that on the (edited version of) the posted XML data, I got:
    15827134 1301 15846291 15613501
    The first number is the "Agreement ID", the next is the "Cycle Code", and the rest are the "Subscriber ID list".

    (The XPath expressions for this are a bit bulky, but once you grok the syntax, it's a lot easier than writing code.)

Re: XML Parsing
by Anonymous Monk on Feb 26, 2015 at 21:50 UTC
    Just an XML parser, as suggested. Consider using one that supports XSLT (such as libxslt ...), which will allow you to _query_ the parsed XML structure to retrieve (without writing cumbersome source-code to do it ...) the values that you want, ignoring the rest. There are copious examples of XSLT all over the Internet, and the same principles apply regardless of programming language used. (In other words, if you're writing if/then statements right now, STOP.)
      XSLT/libxslt is for transformations but it's not needed for querying (XPath), XML/libxml2/XML::LibXML is enough.