2

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.

2 Answers 2

1

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()
Sign up to request clarification or add additional context in comments.

1 Comment

@harshit, the XPath expressions in this answer fulfill all your requirements.
0

I would suggest following XPath xpression:

/thoughts/thought[id='1' and category='Love']/what/text()

I can recommend this tutorial

1 Comment

returns NULL. I don't find the tutorial of much help. Please help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.