2011-08-12 17 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()

है और वास्तव में जब $someConditionfalse()

इस प्रकार यह इस से इस प्रकार है Infinity है कि अगर हम करना चाहते हैं $stringX जबउत्पादन करेंtrue() और $stringY निर्माण करने के लिए जब $Condfalse() है, एक तरह से यह व्यक्त करने के लिए कर रहा है:

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

ऊपर अभिव्यक्ति में वास्तव में concat() समारोह के दो तर्क से एक गैर खाली है।

+1

+1 Dimitre आप हमेशा उत्कृष्ट स्पष्टीकरण प्रदान करते हैं, खासकर XPath से जुड़े प्रश्नों के लिए। मैं अनुभव से बात करता हूं :) – Dan

+0

@ ब्रैकवर्क्स, आपका स्वागत है। –

+2

+1 बहुत अच्छा समाधान –

0

आप नहीं कर सकते; इसके लिए आपको XQuery का उपयोग करना होगा। उदाहरण देखें XQuery Conditional Expressions

या, यदि जिसके परिणामस्वरूप स्ट्रिंग केवल जावा में प्रयोग किया जाता है, तो आप सिर्फ अपने जावा कोड के भीतर 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

मैं एक्सएमएल प्रोसेसिंग के लिए जेएक्सपी का उपयोग कर रहा हूं। इस में इस xquery का उपयोग कैसे करें? –

+0

यदि आप JAXP का उपयोग कर रहे हैं, तो जावा पक्ष पर पुनर्प्राप्त स्ट्रिंग मान के लिए क्यों न केवल परीक्षण करें? –

+0

मेरी समस्या नोड विशेषता मान पर आधारित है जिसे मुझे परिणाम स्ट्रिंग पर निर्णय लेना है। जब मैंने स्ट्रिंग को पुनर्प्राप्त करने का प्रयास किया तो कुछ भी नहीं आया क्योंकि इस नोड में सिर्फ एक विशेषता है। अगर मैं // b [@ id = 23] जैसे conditon देता हूं तो यह एक बुलीन मान लौटा रहा है। –