Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

xpath with condition

Tags:

xml

xpath

How can I get an element in Xpath using complex condition?

For example:

<?xml version="1.0" encoding="UTF-8"?>
<stock xmlns="http://localhost/aaabbb">
<item item-id="1">
 <name xml:format="short">This is a short name</name>
 <name xml:format="long">This is a LONG name</name>
</item>
</stock>

Target: to get the text of the tag WHERE xml:format="long".

Thanks in advance for your help!

like image 459
diemacht Avatar asked Jun 19 '26 14:06

diemacht


2 Answers

Take a look at this: http://www.w3schools.com/xpath/xpath_syntax.asp. The example you are requesting:

The XML document:

<?xml version="1.0" encoding="ISO-8859-1"?>

<bookstore>

<book>
  <title lang="eng">Harry Potter</title>
  <price>29.99</price>
</book>

<book>
  <title lang="eng">Learning XML</title>
  <price>39.95</price>
</book>

</bookstore> 

The XPATH:

//title[@lang='eng']    Selects all the title elements that have an attribute named lang with a value of 'eng'

So you should do this:

//name[@xml:format='long']
like image 136
Morten Frederiksen Avatar answered Jun 21 '26 06:06

Morten Frederiksen


In your specific case the XML document is NOT in the default namespace, therefore an XPath expression like:

/stock/item/name

doesn't select any node.

Use:

/*/*/*[name()='name' and @xml:format = 'long']/text()

or use:

string(/*/*/*[name()='name' and @xml:format = 'long'])

The first expression selects all text child nodes of all elements whose name is name (regardless of the namespace) and that are grand-children of the top element in the XML document.

The second expression produces the string value of the first element in the XML document such that its name is name (regardless of the namespace) and that it is a grand-child of the top element in the XML document.

XSLT - based verification:

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

 <xsl:template match="/">
     <xsl:copy-of select="/*/*/*[name()='name' and @xml:format = 'long']/text()"/>
===========
     <xsl:copy-of select="string(/*/*/*[name()='name' and @xml:format = 'long'])"/>
 </xsl:template>
</xsl:stylesheet>

when this transformation is applied on the provided XML document:

<stock xmlns="http://localhost/aaabbb">
    <item item-id="1">
        <name xml:format="short">This is a short name</name>
        <name xml:format="long">This is a LONG name</name>
    </item>
</stock>

the two Xpath expressions are evaluated and the selected element (by the first) and produced string result (by the second) are copied to the output:

This is a LONG name
===========
This is a LONG name
like image 27
Dimitre Novatchev Avatar answered Jun 21 '26 06:06

Dimitre Novatchev



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!