0

I want to scan following XML and fetch value of id based on condition name=task2 and value=efg.

<node1>
<node2>
    <node3>
        <id>ABC-123</id>
        <condition>
            <task name="task1" operation="and" value="abc" />
            <task name="task2" operation="and" value="efg" />
            <task name="task3" operation="and" value="hij" />
            <task name="task4" operation="or" value="klm" />
            <task name="task5" operation="and" value="nop" />
            <task name="task6" value="uvw" />
        </condition>
    </node3>
    <node3>
        <id>XYZ-987</id>
        <condition>
            <task name="task1" operation="and" value="cde" />
            <task name="task2" operation="and" value="abc" />
            <task name="task5" operation="and" value="nop" />
        </condition>
    </node3>
    <node3>
        <id>RST-567</id>
        <condition>
            <task name="task2" operation="and" value="efg" />
            <task name="task8" operation="and" value="jkl" />
            <task name="task9" operation="and" value="rst" />
            <task name="task10" value="xyz" />
        </condition>
    </node3>
</node2>
</node1>    

I am able to scan and get result as count = 2, using

 String expression = "//node3/condition/task[@name='"+condition.getKey()+"' and @value='"+condition.getValue()+"']";

But not the value of id using following code

String expression = "//node3/condition/task[@name='"+condition.getKey()+"' and @value='"+condition.getValue()+"']/node3/id";

How to get values "ABC-123" and "RST-567" which would be the correct result?

Referring following blog and w3c links
https://xjaphx.wordpress.com/2011/12/24/android-xml-adventure-parsing-xml-using-xpath/
http://www.w3schools.com/xml/xml_xpath.asp
http://www.w3schools.com/xsl/xpath_operators.asp

1
  • Please choose tags wisely. XPath is a subset of XQuery, and there is no XQuery support on android (without additional libraries, which you do not seem to use). I removed the XQuery tag due to being not related to your question. Commented Feb 24, 2016 at 9:33

2 Answers 2

1

You can nest predicates (expression in []) to achieve that, for example :

//node3[condition/task[@name='task2' and @value='efg']]/id
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks :) BTW, which is the best approach, yours or WERO's? Need solution with faster processing.
@AbhinavTyagi har07's solution is very likely faster than wero's, because using the following-sibling:: axis is probably more costly. It depends on the kinds of optimizations your XPath engine makes and usually, the differences do not matter.
1

You can select the ids and filter for the tasks with a following sibling condition:

/node1/node2/node3/id[following-sibling::condition/task[@name='task2' and @value='efg']]

To select only the text values use

/node1/node2/node3/id/text()[../following-sibling::condition/task[@name='task2' and @value='efg']]

4 Comments

Got the result from the first option but second option with text returned exception during evaluation.
something with String Reader...! passing xml as string to input source InputSource inputSrc = new InputSource(new StringReader(xml)); XPath xpath = XPathFactory.newInstance().newXPath(); String result = (String)xpath.evaluate(expression, inputSrc, XPathConstants.STRING);
that seems to be another problem. Comments are not a good place to discuss exceptions, but you can always post another question.
I am fine with your first option :)

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.