Return a string value based on XPATH condition
If I have the below XML, how to specify a xpath to return a 开发者_开发问答string based on a condition. For example here if //b[@id=23] then "Profit" else "Loss"
<a>
<b id="23"/>
<c></c>
<d></d>
<e>
<f id="23">
<i>123</i>
<j>234</j>
<f>
<f id="24">
<i>345</i>
<j>456</j>
<f>
<f id="25">
<i>678</i>
<j>567</j>
<f>
</e>
</a>
I. XPath 2.0 solution (recommended if you have access to an XPath 2.0 engine)
(: XPath 2.0 has if ... then ... else ... :)
if(//b[@id=23])
then 'Profit'
else 'Loss'
II. XPath 1.0 solution:
Use:
concat(substring('Profit', 1 div boolean(//b[@id=23])),
substring('Loss', 1 div not(//b[@id=23]))
)
Verification using XSLT 1.0:
This transformation:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:value-of select=
"concat(substring('Profit', 1 div boolean(//b[@id=23])),
substring('Loss', 1 div not(//b[@id=23]))
)"/>
</xsl:template>
</xsl:stylesheet>
when applied on the provided XML document (corrected to make it well-formed):
<a>
<b id="23"/>
<c></c>
<d></d>
<e>
<f id="23">
<i>123</i>
<j>234</j>
</f>
<f id="24">
<i>345</i>
<j>456</j>
</f>
<f id="25">
<i>678</i>
<j>567</j>
</f>
</e>
</a>
produces the wanted, correct result:
Profit
When we replace in the XML document:
<b id="23"/>
with:
<b id="24"/>
again the correct result is produced:
Loss
Explanation:
We use the fact that:
substring($someString, $N)
is the empty string for all $N > string-length($someString)
.
Also, the number Infinity
is the only number greater than the string-length of any string.
Finally:
number(true())
is 1
by definition,
number(false())
is 0
by definition.
Therefore:
1 div $someCondition
is 1
exactly when the $someCondition
is true()
and is Infinity
exactly when $someCondition
is false()
Thus it follows from this that if we want to produce $stringX
when $Cond
is true()
and to produce $stringY
when $Cond
is false()
, one way to express this is by:
concat(substring($stringX, 1 div $cond),
substring($stringY, 1 div not($cond)),
)
In the above expression exactly one of the two arguments of the concat()
function is non-empty.
You can't; you'd have to use XQuery for this. see e.g. XQuery Conditional Expressions
Or, if the resulting string is only used within Java, you can just process the value returned by XPath within your Java code:
XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();
XPathExpression expr = xpath.compile("//b[@id=23]");
boolean result = expr.evaluate(doc, XPathConstants.BOOLEAN);
if (result) return "Profit";
else return "Loss";
精彩评论