Reputation: 3846
I have the following XML:
<thoughts>
<thought>
<id>1</id>
<category>Leadership</category>
<what>sometext</what>
<who>sometext</who>
</thought>
<thought>
<id>2</id>
<category>Leadership</category>
<what>sometext</what>
<who>sometext</who>
</thought>
... 100s of category Leadership
<thought>
<id>1</id>
<category>Love</category>
<what>sometext</what>
<who>sometext</who>
</thought>
<thought>
<id>2</id>
<category>Love</category>
<what>sometext</what>
<who>sometext</who>
</thought>
... 100s of category Love
... and so on up to about ten categories
</thoughts>
I want to select a thought(what) for a given id and category. I am doing this in Java. I tried the following:
"/thought[id='1']/thought[category='Love']/what/text()"
Java:
XPathFactory factory = XPathFactory.newInstance();
XPath xPath = factory.newXPath();
XPathExpression expr1 = xPath.compile("/thought[id='1']/thought[category='Love']/what/text()");
Object result1 = expr1.evaluate(doc, XPathConstants.NODESET);
NodeList nodes1 = (NodeList) result1;
I have also tried following XPathExpressions:
/thoughts/thought[id='1']/thought[category=`Love`]/what/text()
I am new to XML and XPath.
Upvotes: 2
Views: 121
Reputation: 243449
Use:
/*/thought[id = '1' and category = 'Love']/what
This selects any what
element that is a child of a thought
element, that has an id
child with string value "1"
and that has a category
child with string value "Love"
, and that (the thought
element) is a child of the top element of the XML document.
In case you need the text node children of the element(s) selected above, use:
/*/thought[id = '1' and category = 'Love']/what/text()
In case you need just the string value of the (first of) the above text node(s), use:
string(/*/thought[id = '1' and category = 'Love']/what)
XSLT - based verification:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:copy-of select="/*/thought[id = '1' and category = 'Love']/what"/>
============
<xsl:copy-of select="/*/thought[id = '1' and category = 'Love']/what/text()"/>
============
<xsl:copy-of select="string(/*/thought[id = '1' and category = 'Love']/what)"/>
</xsl:template>
</xsl:stylesheet>
When this transformation is applied on the following XML document (the provided one with distinct value for the wanted node):
<thoughts>
<thought>
<id>1</id>
<category>Leadership</category>
<what>sometext</what>
<who>sometext</who>
</thought>
<thought>
<id>2</id>
<category>Leadership</category>
<what>sometext</what>
<who>sometext</who>
</thought>
... 100's of with category Leadership
<thought>
<id>1</id>
<category>Love</category>
<what>some Love text 1</what>
<who>sometext</who>
</thought>
<thought>
<id>2</id>
<category>Love</category>
<what>sometext</what>
<who>sometext</who>
</thought>
... 100's of with category Love
... and so on up to about ten categories
</thoughts>
the three XPath expressions are evaluated and the results of these evaluations are copied to the output, separated visually by a handy delimiter:
<what>some Love text 1</what>
============
some Love text 1
============
some Love text 1
Update:
In a comment the OP has added the requirement that not only what
, but also who
should be selected.
Here are the corresponding new XPath expressions for this case:
/*/thought[id = '1' and category = 'Love']/*[self::what or self::who]
/*/thought[id = '1' and category = 'Love']/*[self::what or self::who]/text()
Upvotes: 1
Reputation: 12837
I would suggest following XPath xpression:
/thoughts/thought[id='1' and category='Love']/what/text()
I can recommend this tutorial
Upvotes: 0