1

I have sample xml below, I would like to extract values from the tags for example value=3. Since there are repeated tags I am finding challenge to do this in unix.

<Request> <Destination> <Parameters> <Parameter> <key>a</key> <value>1</value> </Parameter> <Parameter> <key>b</key> <value>2</value> </Parameter> <Parameter> <key>c</key> <value>3</value> </Parameter> </Parameters> <Proxy> <Destination> <Parameters> <Parameter> <key>a</key> <value>1</value> </Parameter> <Parameter> <key>b</key> <value>2</value> </Parameter> <Parameter> <key>c</key> <value>3</value> </Parameter> </Parameters> </Destination> </Proxy> </Destination> 

3 Answers 3

1

Generally it is more compact to use XQuery/XPath 3 (e.g. in my implementation) than XSLT. Depending what you mean by "extract values", you can do one of these:

xidel req.xml --extract '//value' 

to get all values

1 2 3 1 2 3 

or with a prefix:

xidel req.xml -e '//value/("value="||.)' 

to get

value=1 value=2 value=3 value=1 value=2 value=3 

To get all keys with a certain value:

xidel req.xml -e '//*[value="3"]/key' c c 

Or all values with a certain key:

xidel req.xml -e '//*[key="b"]/value' 2 2 
Sign up to request clarification or add additional context in comments.

Comments

0

You can try using a command line XSLT processor like 'xsltproc' or 'xalan' and parse your .xml file using a .xsl stylesheet. Here's a stylesheet which refers to your sample xml data.

I am assuming there is an end tag corresponding to 'Request' at the end of your file.

<xsl:stylesheet xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" version = "1.0"> <xsl:output method = "text"/> <xsl:template match = "Request"> <xsl:for-each select = "Destination/Parameters/Parameter"> <xsl:text>value=<xsl:value-of select = "@value"/> </xsl:text> </xsl:for-each> <xsl:template match = "Proxy"> <xsl:for-each select = "Destination/Parameters/Parameter"> <xsl:text>value=<xsl:value-of select = "@value"/> </xsl:text> </xsl:for-each> </xsl:template> </xsl:template> </xsl:stylesheet> 

Comments

0

In perl:

#!/usr/bin/env perl use strict; use warnings; use XML::Twig; my $twig = XML::Twig -> new -> parsefile ( 'your_xml_file' ); print $_ -> text,"\n" for $twig -> findnodes('//value'); 

Which reduces to a one liner:

perl -MXML::Twig -e 'print $_ -> text,"\n" for XML::Twig -> parse ( do { local $/;<> } )-> findnodes('//value')' your_file.xml 

If you want to get a bit more complicated with it, you can use xpath expressions to find particular things:

#!/usr/bin/env perl use strict; use warnings; use XML::Twig; my $twig = XML::Twig -> new -> parsefile ( 'your_file.xml' ); foreach my $node ( $twig -> findnodes('//value[string()="3"]/../') ) { print $node -> first_child_text('key'),"\n"; } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.