2011-08-12 41 views
13

如果我有下面的XML,那么如何指定xpath根据条件返回一个字符串。例如这里if //b[@id=23] then "Profit" else "Loss"返回一个基于XPATH条件的字符串值

<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> 
+0

好问题,+1。查看我的答案,获取纯XPath 1.0单行表达式。 :) –

+0

还增加了广泛的解释和明显的XPath 2.0解决方案。 –

回答

19

一的XPath 2.0解决方案(建议,如果你有访问XPath 2.0引擎)

(: XPath 2.0 has if ... then ... else ... :) 

    if(//b[@id=23]) 
    then 'Profit' 
    else 'Loss' 

II。的XPath 1.0溶液

使用:

concat(substring('Profit', 1 div boolean(//b[@id=23])), 
     substring('Loss', 1 div not(//b[@id=23])) 
    ) 

验证使用XSLT 1.0

这种变换:

<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> 

当所提供的XML文档施加(校正以使其形成良好):

<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> 

产生想要的,正确的结果

Profit 

当我们更换XML文档在:

<b id="23"/> 

<b id="24"/> 

再次正确的结果产生

Loss 

说明

我们使用的事实是:

substring($someString, $N) 

是所有$N > string-length($someString)空字符串。

另外,数字Infinity是大于任何字符串的字符串长度的唯一数字。

最后:

number(true())1顾名思义,

number(false())0定义。

因此:

1 div $someCondition

1正是当$someConditiontrue()

Infinity什么时候$someConditionfalse()

因此,由此得出,如果我们想当产生是true()并产生$stringY$Condfalse(),表达此的一种方式是通过

concat(substring($stringX, 1 div $cond), 
     substring($stringY, 1 div not($cond)), 
    ) 

在上述表达式中完全concat()函数的两个参数中的一个非空

+1

+1 Dimitre您始终提供出色的解释,特别是涉及XPath的问题。我从经验发言:) – Dan

+0

@Bracketworks,不客气。 –

+2

+1非常酷的解决方案 –

0

你不能;你必须为此使用XQuery。见例如XQuery Conditional Expressions

或者,如果得到的字符串中的Java只用,你可以处理你的Java代码中与XPath返回的值:

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"; 
+0

我正在使用JAXP进行xml处理。如何在这个使用这个xquery? –

+0

如果您使用JAXP,那么为什么不直接在Java端测试检索到的字符串值? –

+0

我的问题是基于我必须决定结果字符串的节点属性值。当我试图检索字符串时没有任何内容,因为此节点只有一个属性。如果我给出像// b [@ id = 23]那样的条件,它将返回一个可靠的值。 –

相关问题