2011-07-20 16 views
10

के साथ अपने माता-पिता के भीतर किसी तत्व की स्थिति पाएं XSLT कोड (जो मैं नहीं करने जा रहा हूं) को फिर से लिखने के अलावा, क्या उसके माता-पिता के भीतर किसी तत्व की स्थिति को ढूंढने का कोई तरीका है, जब संदर्भ मनमाने ढंग से किसी और चीज पर सेट किया जाता है? यहाँ एक उदाहरण है:एक्सएसएलटी/XPath

<!-- Here are my records--> 
<xsl:for-each select="/path/to/record"> 
    <xsl:variable name="record" select="."/> 

    <!-- At this point, I could use position() --> 
    <!-- Set the context to the current record --> 
    <xsl:for-each select="$record"> 

    <!-- At this point, position() is meaningless because it's always 1 --> 
    <xsl:call-template name="SomeTemplate"/> 
    </xsl:for-each> 
</xsl:for-each> 


<!-- This template expects the current context being set to a record --> 
<xsl:template name="SomeTemplate"> 

    <!-- it does stuff with the record's fields --> 
    <xsl:value-of select="SomeRecordField"/> 

    <!-- How to access the record's position in /path/to or in any other path? --> 
</xsl:template> 

नोट: इस सरल उदाहरण है। मुझे SomeTemplate आदि के नए पैरामीटर को पास करने जैसे स्पष्ट समाधानों को लागू करने से मुझे कई बाधाएं हैं। मैं वास्तव में केवल SomeTemplate के आंतरिक को संशोधित कर सकता हूं।

नोट: मैं Xalan 2.7.1 EXSLT के साथ उपयोग कर रहा हूं। तो उन चालें उपलब्ध हैं

कोई विचार?

उत्तर

24

आप इस्तेमाल कर सकते हैं

<xsl:value-of select="count(preceding-sibling::record)" /> 

या यहाँ तक कि, सामान्य रूप से,

<xsl:value-of select="count(preceding-sibling::*[name() = name(current())])" /> 
बेशक

यदि आप एक, यानी नोड्स की सूची है कि एक समान नहीं है की प्रक्रिया इस दृष्टिकोण से काम नहीं चलेगा:

<xsl:apply-templates select="here/foo|/somewhere/else/bar" /> 

ऐसी स्थिति में स्थिति जानकारी खो जाती है, जब तक आप सेंट एक चर में यह अयस्क और कहा जाता है टेम्पलेट है कि पारित:

<xsl:variable name="pos" select="position()" /> 
<xsl:for-each select="$record"> 
    <xsl:call-template name="SomeTemplate"> 
    <xsl:with-param name="pos" select="$pos" /> 
    </xsl:call-template> 
</xsl:for-each> 

लेकिन स्पष्ट रूप से है कि पुनर्लेखन कुछ कोड है, जो मुझे पता है आप बचना चाहते हैं का मतलब होगा।


अंतिम संकेत: position() करता आप अपनी मूल भीतर नोड की स्थिति नहीं बता। यह आपको वर्तमान नोड की स्थिति बताता है जो नोड्स की सूची के सापेक्ष है जो आप अभी प्रसंस्करण कर रहे हैं

यदि आप केवल एक माता-पिता के भीतर नोड्स (यानी "टेम्पलेट्स को लागू करें" या "लूप ओवर") नोड्स को संसाधित करते हैं, तो यह वही होता है। यदि आप नहीं करते हैं, तो यह नहीं है।

अंतिम संकेत # 2: यह

<xsl:for-each select="/path/to/record"> 
    <xsl:variable name="record" select="."/> 
    <xsl:for-each select="$record"> 
    <xsl:call-template name="SomeTemplate"/> 
    </xsl:for-each> 
</xsl:for-each> 

है इस के बराबर है:

<xsl:for-each select="/path/to/record"> 
    <xsl:call-template name="SomeTemplate"/> 
</xsl:for-each> 

लेकिन बाद काम करता है बिना position() के अर्थ को नष्ट करने। टेम्पलेट को कॉल करने से संदर्भ नहीं बदला जाता है, इसलिए . कॉल किए गए टेम्पलेट के साथ सही नोड का संदर्भ लेंगे।

+2

आप आदमी हैं! मैंने आपके सुझाव को '1 + गिनती (पूर्ववर्ती-भाई :: *) 'में अनुकूलित किया और यह एक आकर्षण की तरह काम किया! –

+0

आपके अपडेट के बारे में: असली दुनिया के उदाहरण में, रिकॉर्ड हमेशा एक समान होते हैं (हालांकि हमेशा 'रिकॉर्ड' नहीं कहा जाता है) क्योंकि वे एक टेबल मॉडल करते हैं। तो दो "असंगत" XPath नोड-सेट का कोई यूनियन ऑपरेटर नहीं है।परिवर्तनीय समाधान वास्तविक दुनिया कोड –

+0

की जटिलता के कारण काम नहीं करेगा 'स्थिति() 'के बारे में अतिरिक्त संकेतों के लिए धन्यवाद। चूंकि मैं हमेशा वर्दी तत्वों पर लूपिंग कर रहा हूं, मेरे मामले में, लूपिंग स्थिति उसके माता-पिता के भीतर तत्व सूचकांक के साथ मेल खाती है। –

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

  • कोई संबंधित समस्या नहीं^_^