2009-04-06 21 views
18

के साथ तत्वों की गणना करने के लिए मुझे एक XML फ़ाइल में तत्वों की संख्या गिनने की आवश्यकता है, जिसमें एक विशेष मान है (विशिष्टता को सत्यापित करने के लिए)। एक्सएमएल फ़ाइल इस तरह दिखती है:XSLT किसी दिए गए मान

संपादित करें: मैंने मूल "सरलीकृत" एक्सएमएल को वास्तविक बालों वाली गड़बड़ी के साथ किसी को डिज़ाइन किया है। दुर्भाग्यवश, यह संपादित किए जाने तक सभी पिछले उत्तर वास्तव में भ्रमित और गलत बनाने जा रहा है।

<root> 
    <ac> 
    <Properties> 
    <Property Name="Alive"> 
     <Properties> 
     <Property Name="ID"> 
     <Properties> 
      <Property Name="Value"> 
      <long>11007</long> 
      </Property> 
     </Properties> 
     </Property> 
     </Properties> 
    </Property> 
    <Property Name="Dead"> 
     <Properties> 
     <Property Name="ID"> 
     <Properties> 
      <Property Name="Value"> 
      <long>11008</long> 
      </Property> 
     </Properties> 
     </Property> 
     </Properties> 
    </Property> 
    ... 
    <Property Name="MostlyDeadAllDay"> 
     <Properties> 
     <Property Name="ID"> 
     <Properties> 
      <Property Name="Value"> 
      <long>99001</long> 
      </Property> 
     </Properties> 
     </Property> 
     </Properties> 
    </Property> 
    </Properties> 
    </ac> 
</root> 

मैं एक चर को देखने के लिए कैसे जिंदा/मृत स्तर पर संपत्तियों की कई लंबे मूल्य (आईडी) के रूप में टेम्पलेट पैरामीटर में परिभाषित परिभाषित करने के लिए कोशिश कर रहा हूँ। इन पंक्तियों के साथ कुछ (हालांकि मुझे लगता है यह गलत है) ...

<xsl:param name="parPropId"/> 
<xsl:variable name="countProperties"> 
    <xsl:value-of select="count(/root/ac/ 
     Properties/Property/ 
     Properties/Property[@Name = 'ID']/ 
     Properites/Property[@Name = 'Value']/long = $parPropId)"/> 
</xsl:variable> 

एक से अधिक संपत्ति "आईडी" स्तर पर परिभाषित तत्वों हो सकता है। लेकिन मैं काफी हद तक निश्चित हूं कि मैं "आईडी" के तहत केवल एक संपत्ति तत्व ("मान") पर और "मूल्य" के तहत केवल एक "लंबा" तत्व पर भरोसा कर सकता हूं।

[अस्वीकरण] जो भी समग्र XML फ़ाइल डिज़ाइन किया गया है, मैं वास्तव में काम कर रहा हूं, मुझे पता नहीं था कि XML को कैसे व्यवस्थित किया जाए (उदाहरण के लिए, गुणों के बनाम गुणों का पिछला उपयोग)। मुझे डर है कि मेरी एक्सएसएलटी सोच अस्थायी रूप से लगी हुई है :) नतीजतन। [/ अस्वीकरण]

+0

XPath अभिव्यक्ति आपने "गलत" क्यों दिखायी है? मुझे इसके साथ कुछ भी गलत नहीं दिख रहा है। – Cerebrus

+0

सुनिश्चित नहीं है। मैंने उपरोक्त एक्सएमएल को सरल बना दिया। वास्तविक xpath यह है: "/// गुण/संपत्ति/गुण/संपत्ति [@ नाम = 'आईडी']/गुण/संपत्ति [@ नाम = 'मान']/लंबा"। यदि आप सही हैं, तो मैं "[long = $ parPropId]" के साथ "/ long" को प्रतिस्थापित कर सकता हूं। गलत लगता है क्योंकि इससे दो "[]" ओप एक साथ सही होंगे। –

+0

मैंने सत्यापित किया कि वर्टेक का टेक्स्ट() सही टेक्स्ट देता है (यानी "/// गुण/संपत्ति/गुण/संपत्ति [@ नाम = 'आईडी']/गुण/संपत्ति [@ नाम = 'मान']/लंबा/पाठ () "मेरी आईडी प्राप्त करता है, लेकिन उसकी विधि का उपयोग करके मेरी गिनती अभी भी विफल रही है। –

उत्तर

36

यह XPath:

count(//Property[long = '11007']) 

रूप में एक ही मान देता है:

count(//Property/long[text() = '11007']) 

... सिवाय इसके कि पहली गणना Property नोड्स जो मानदंड से मेल खाते हैं और दूसरी गणना long मानदंड से मेल खाने वाले बच्चे नोड्स।

आपकी टिप्पणी के अनुसार और दो बार अपने प्रश्न को पढ़ने के बाद, मेरा मानना ​​है कि आप मानदंडों के संयोजन के आधार पर विशिष्टता खोजना चाहते हैं। इसलिए, वास्तविकता में, मुझे लगता है कि आप वास्तव में कई स्थितियों की जांच कर रहे हैं।

count(//Property[@Name = 'Alive' and long = '11007']) 
बेशक

, आप अपने टेम्पलेट में पैरामीटर के लिए मानों को बदल जाएगा: क्योंकि यह एक ही बात के रूप में इसका मतलब है

count(//Property[@Name = 'Alive'][long = '11007']) 

: निम्नलिखित के रूप में अच्छी तरह से काम करेगा। उपरोक्त कोड केवल बिंदु को दर्शाता है।

संपादित (के बाद प्रश्न संपादित)


आप एक्सएमएल भयानक होने के बारे में काफी सही थे। वास्तव में, यह एक कमजोर CodingHorror उम्मीदवार है! मुझे वर्तमान में मौजूद "संपत्ति" नोड का ट्रैक रखने के लिए याद रखना था। मै तुम्हारा दर्द समझ सकता हू!

ये रहा:

count(/root/ac/Properties/Property[Properties/Property/Properties/Property/long = $parPropId]) 

ध्यान दें कि मैं अन्य सभी चेक (आईडी और मूल्य के लिए) को हटा दिया है। वे आवश्यक नहीं हैं क्योंकि आप एक्सएमएल में पदानुक्रम का उपयोग कर प्रासंगिक नोड पर पहुंचने में सक्षम हैं। साथ ही, आपने पहले से ही उल्लेख किया है कि विशिष्टता की जांच केवल long तत्व की सामग्री पर आधारित है।

+0

इस xpath समकक्ष पर मुझे शिक्षित करने के लिए धन्यवाद! जो कुछ भी आप कह रहे हैं वह सही समझ में आता है (मेरे मध्यम एक्सएसएल/XPath अनुभव के आधार पर)। असल में, मेरे पास एकाधिक मानदंड नहीं हैं, आईडी की मुझे परवाह है। गैर-शून्य मान [arrrgghh] देने के लिए बस उस गिनती को प्राप्त नहीं किया जा सकता है। –

+0

आश्चर्यजनक रूप से, इन मिक्सर कभी-कभी इन आईडी के लिए 'लंबे' के बजाय 'स्ट्रिंग' और 'int' का उपयोग करते हैं। आपने मुझे कोडिंग हॉरर को सबमिट करने के लिए प्रेरित किया है! मैं आपके समाधान के '/ लंबे' भाग को हटा देता हूं (जो अब काम करता है)। मैं इसे उत्तर के रूप में फ़्लैग कर रहा हूं, और मेरे साथ असर के लिए एक लाख धन्यवाद। –

-2
<xsl:variable name="count" select="count(/Property/long = $parPropId)"/> 

अन परीक्षण किया गया लेकिन मुझे लगता है कि यह काम करना चाहिए। मैं संपत्ति नोड्स रूट नोड के प्रत्यक्ष बच्चे हैं यह सोचते हैं रहा हूँ और वजह peformance

के लिए अपने वंशज चयनकर्ता बाहर ले
2

आपका xpath बस थोड़ी दूर है:

count(//Property/long[text()=$parPropId]) 

संपादित करें: सेरेब्रुस काफी ठीक ही बताते हैं कि आपके ओपी में कोड (नोड के निहित मूल्य का उपयोग करके) आपके उद्देश्यों के लिए बिल्कुल ठीक है। वास्तव में, चूंकि यह काफी संभावना है कि आप "लंबे" नोड के बजाय "संपत्ति" नोड के साथ काम करना चाहते हैं, तो संभवतः बेहतर टेक्स्ट() xpath की तुलना में //Property[long=$parPropId] के लिए पूछने के लिए, हालांकि आप बाद वाले के लिए केस बना सकते हैं पठनीयता आधार पर।

मैं क्या कह सकता, मैं थोड़ा थक आज :) हूँ

+0

क्या सोचें! आपके पास 666 उत्तर हैं! महत्वपूर्ण! – Cerebrus

+0

और पूरी तरह से संयोग से दिमित्री की पीठ अपने क्रूसेड पर। – annakata

+0

और संयोग से नहीं, अन्नकाता ने फिर से किसी भी कॉम को हटा दिया ent जो बताता है कि उसके जवाब में वास्तव में क्या गलत है। –

संबंधित मुद्दे