2011-04-13 11 views
6

मैं अपने समस्या का समाधान खोजने के लिए चारों ओर खोज की है, लेकिन मैं सिर्फ अधिक सवाल मिल गया ...गतिशील QName के साथ XSLT कॉल-टेम्पलेट?

निम्न XML पर विचार करें:

<dynamicStuff> 
     <dyn id="name1">...</dyn> 
     <dyn id="name2">...</dyn> 
     <dyn id="name3">...</dyn> 
     <dyn id="name4">...</dyn> 
</dynamicStuff> 

और लगता है मुझे इस प्रकार एक XSLT फ़ाइल है :

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:template name="name1">  
     ... 
    </xsl:template> 

    <xsl:template name="name2">  
     ... 
    </xsl:template> 

    <xsl:template name="name3">  
     ... 
    </xsl:template> 

    <xsl:template name="name4">  
     ... 
    </xsl:template> 

</xsl:stylesheet> 

मुझे क्या करना चाहते हैं एक दूसरा XSLT फ़ाइल से है गतिशील रूप से जो निर्धारित टेम्पलेट कुछ इस तरह से कॉल करने के लिए:

<xsl:variable name="templateName"> 
    <xsl:value-of select="dyn/@id"/> 
</xsl:variable> 

<xsl:call-template name="$templateName"/> 

उदासी अपने काम नहीं कर रहा, मुझे विश्वास है जब मैं कहता हूँ कि मैं अलग सामान का एक बहुत कोशिश की है, हालांकि यह यह या तो काम नहीं करता है ... इतना आसान लगता है

मैं कुछ याद आ रही है?

संपादित करें:

मैं सफलतापूर्वक निम्नलिखित किया है:

<xsl:template name="staticName"> 
    <xsl:param name="id" /> 

    <xsl:if test="$id = 'name1'">....</xsl:if> 
    <xsl:if test="$id = 'name2'">....</xsl:if> 
    ... 
</xsl:template> 

इस तरह से कॉलिंग:

<xsl:call-template name="staticName"> 
    <xsl:with-param name="id" select="@id"/> 
</xsl:call-template> 

सुई कहने के लिए कि यह कैसे असुविधाजनक है ... के पहले मेरा पूरा कोड उस स्थिर नाम से बंधेगा (कल्पना करें कि मुझे यह कॉल एक दर्जन फाइलों में करने की ज़रूरत है) ... दूसरा, मेरे पास एक समूह (संयुक्त) संबंधित cont होगा जब यह अधिक अलग किया जा सकता एक ही टेम्पलेट के अंदर ईएनटी ... एक बुरा सपना किसी भी प्रकाश के लिए पहले से

uu सिस्टम को अपग्रेड करने यह रास्ता नहीं मैं की जरूरत है जो मैं चाहता करती है, लेकिन नहीं ...

धन्यवाद इस मामले पर!

उत्तर

6

http://www.w3.org/TR/xslt#named-templates

name विशेषता का मान QName, है जो [2.4 Qualified Names] में वर्णित के रूप में विस्तारित किया गया है।

इसका मतलब है कि न तो अभिव्यक्ति और न ही एवीटी है।

स्पष्ट xsl:call-template निर्देश ठीक है कि क्या तर्क निर्देश या पैटर्न द्वारा तरह से मेल खाते हैं:

<xsl:template match="dyn[@id='name1']" mode="dynamic"> 
<xsl:call-template name="name1"/> 
</xsl:template> 

एक और दृष्टिकोण का नाम है टेम्पलेट संदर्भ ...

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:variable name="vTemplate" select="document('')/*/xsl:template"/> 
    <xsl:template match="dyn"> 
     <xsl:apply-templates select="$vTemplate[@name = current()/@id]"/> 
    </xsl:template> 
    <xsl:template match="xsl:template[@name='name1']" 
        name="name1"> one </xsl:template> 
    <xsl:template match="xsl:template[@name='name2']" 
        name="name2"> two </xsl:template> 
    <xsl:template match="xsl:template[@name='name3']" 
        name="name3"> three </xsl:template> 
    <xsl:template match="xsl:template[@name='name4']" 
        name="name4"> four </xsl:template> 
</xsl:stylesheet> 

आउटपुट:

one two three four 


नोट: क्योंकि यह तकनीक मूल XML फ़ाइल की बजाय XSLT को संसाधित करने के लिए document('') का उपयोग करती है, इसलिए संसाधित मूल दस्तावेज़ नामित टेम्पलेट्स में उपलब्ध नहीं है। हालांकि, आप स्पष्ट रूप से टेम्पलेट्स के लिए पैरामीटर के रूप में current() पारित कर सकते हैं अगर जरूरत:

<xsl:template match="dyn"> 
     <xsl:apply-templates select="$vTemplate[@name = current()/@id]"> 
      <xsl:with-param name="current" select="current()"/> 
     </xsl:apply-templates> 
    </xsl:template> 

यदि आवश्यक हो, $current मूल दस्तावेज का उपयोग करने के लिए इस्तेमाल किया जा सकता है:

<xsl:template match="xsl:template[@name='name1']" name="name1"> 
     <xsl:param name="current"/> 
     <xsl:value-of select="$current/@id"/> 
     <xsl:text> becomes one</xsl:text> 
    </xsl:template> 

यदि आवश्यक हो, $current फिर से हो सकता है for-each का उपयोग कर मौजूदा नोड के रूप में स्थापित:

<xsl:template match="xsl:template[@name='name2']" name="name2"> 
    <xsl:param name="current"/> 
    <xsl:for-each select="$current"> 
      <xsl:value-of select="@id"/> 
      <xsl:text> becomes two</xsl:text> 
    </xsl:for-each> 
</xsl:template> 
1

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

<xsl:if test="$templateName = 'name1'"> 
    <xsl:call-template name="name1"/> 
</xsl:if> 
+0

दुख की बात है कि मेरी संभावित घटनाओं की संख्या छोटी नहीं है .. हालांकि यह सीमित है। बड़ी समस्या यह है कि यह सभी को एक फ़ाइल में समूहित नहीं किया गया है – Fawix

+0

वैसे समस्या यह है कि मेरे पास xml के लिए एक निश्चित लेआउट नहीं है और यह पहचानने के लिए आईडी के साथ कई अलग-अलग टैग (और कई अलग-अलग xmls) में हो सकता है, और मेरा एक्सएसएलटी नाम निर्धारित करने में सक्षम होने के लिए बहुत सामान्य है .. अब तक पैरामीटर का उपयोग कर कामकाज सबसे अच्छा था। – Fawix

0

आप प्रयास कर रहे हैं क्या है नहीं सीधे संभव, लेकिन क्यों बस पहली जगह में id विशेषता के महत्व पर मेल नहीं? यदि आप पूरी तरह कहा जाता है टेम्पलेट के अविवेक की जरूरत है, तो उस id से मेल खाता है टेम्पलेट से इसे कहते (नीचे name4 देखें):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="/"> 
     <t><xsl:apply-templates select="dynamicStuff/dyn"/></t> 
    </xsl:template> 
    <!-- match on attribute value --> 
    <xsl:template match="dyn[@id='name1']">name1</xsl:template> 
    <xsl:template match="dyn[@id='name2']">name2</xsl:template> 
    <xsl:template match="dyn[@id='name3']">name3</xsl:template> 
    <xsl:template match="dyn[@id='name4']"> 
     <xsl:call-template name="name4"/> 
    </xsl:template> 
    <!-- named templates --> 
    <xsl:template name="name1">name1</xsl:template> 
    <xsl:template name="name2">name2</xsl:template> 
    <xsl:template name="name3">name3</xsl:template> 
    <xsl:template name="name4">name4</xsl:template> 
</xsl:stylesheet> 

इनपुट:

<dynamicStuff> 
    <dyn id="name1">...</dyn> 
    <dyn id="name2">...</dyn> 
    <dyn id="name3">...</dyn> 
    <dyn id="name4">...</dyn> 
</dynamicStuff> 

आउटपुट:

<t>name1name2name3name4</t> 
+0

उत्तर के लिए धन्यवाद! दुख की बात है कि मेरे पास सिर्फ एक एक्सएमएल नहीं है और यह कई अलग-अलग टैग (उसी आईडी द्वारा पहचाना गया) में हो सकता है, इसलिए dyn [@ id = 'name1'] के साथ मैपिंग मेरे कोड को बहुत अधिक बना देगा क्योंकि मुझे हर टैग को मैप करना होगा सभी एक्सएमएल फाइलें – Fawix

1

आमतौर पर जब कोई व्यक्ति ऐसा करने की कोशिश करता है, तो इसका मतलब वे गिरफ्तारी ई xsl की पूर्ण शक्ति से अवगत नहीं है: लागू-टेम्पलेट्स। एक्सएसएलटी में गतिशील प्रेषण करने का तरीका xsl का उपयोग करना है: लागू-टेम्पलेट्स। उदाहरण के लिए, के लिए समस्या का हवाला दिया, इस तरह के

<xsl:template match="dyn[@id='name1']">...</xsl:template> 
<xsl:template match="dyn[@id='name2']">...</xsl:template> 
<xsl:template match="dyn[@id='name3']">...</xsl:template> 

के रूप में टेम्पलेट नियमों लिखना और फिर <xsl:apply-templates select="dyn"/> का उपयोग प्रेषण करने के लिए।

0

आप पुराने सैक्सन-बी या नए सैक्सन-पीई या XSLT प्रोसेसर के रूप में सैक्सन-ई का उपयोग कर रहे हैं, तो आप गतिशील टेम्पलेट प्राप्त करने के लिए एक सेक्सन एक्सटेंशन का उपयोग कर सकते हैं कॉल:

<xsl:variable name="templateName"> 
    <xsl:value-of select="dyn/@id"/> 
</xsl:variable> 

<saxon:call-template name="{$templateName}"/> 

के लिए मत भूलना एक्सएसएल-स्टाइलशीट तत्व में सैक्सन-नेमस्पेस घोषित करें:

<xsl:stylesheet xmlns:saxon="http://saxon.sf.net/" [...] >