2013-01-15 20 views
6

मैं एक्सएसएलटी के लिए काफी नया हूं और इसलिए मैं जानना चाहता हूं कि किसी विशेषता के अस्तित्व की जांच करने के लिए सबसे अच्छा अभ्यास क्या है। मेरा एक्सएमएल ऐसा कुछ दिखता है:एक्सएसएलटी यदि विशेषता मौजूद है/अन्य

<root> 
    <languages> 
     <lang id="EN">English<lang> 
     <lang id="FR">French<lang> 
     <lang id="DE">German</lang> 
    </languages> 
    <items> 
     <item lang="EN">test 1</item> 
     <item>test 2</item> 
     <item lang="FR">item 3</item> 
    </items> 
</root> 

ध्यान दें कि 'आइटम' तत्व के लिए 'लैंग' विशेषता वैकल्पिक है।

अब मैं एक-लूप का उपयोग कर वस्तुओं के माध्यम से लूप करना चाहता हूं, जबकि यह जांच कर रहा है कि इसमें "लैंग" -ट्रिब्यूट है या नहीं। यदि ऐसा होता है, तो मैं आईडी का उपयोग कर पूरी स्ट्रिंग लाने के लिए चाहता हूं (उदाहरण के लिए एन -> 'अंग्रेजी')। यदि विशेषता सेट नहीं है, तो मैं इसे "कोई भाषा सेट" या कुछ समान लिखना नहीं चाहता हूं।

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

<xsl:for-each select="//root/items/item"> 
    <xsl:variable name="cur_lang" select="@lang" /> <!-- first I store the attr lang in a variable --> 
    <xsl:choose> 
     <xsl:when test="@lang"> <!-- then i test if the attr exists --> 
      <xsl:value-of select="//root/languages/lang[@id=$cur_lang]" /> <!-- if so, parse the element value --> 
     </xsl:when> 
     <xsl:otherwise> 
      No language set <!-- else --> 
     </xsl:otherwise> 
    </xsl:choose> 
</xsl:for-each> 

कोई सुझाव/टिप्स?

+2

आप का एक उदाहरण जोड़ सकते हैं (अच्छी तरह से गठित होने के लिए निर्धारित) आपके द्वारा प्रदान किए गए इनपुट को सटीक आउटपुट क्या दिया जाना चाहिए? –

+0

कार्लो, आप वांछित आउटपुट प्रदान करना भूल गए - मैंने सोचा कि आप विस्तारित भाषा स्ट्रिंग को मौजूदा 'lang' विशेषता मान को प्रतिस्थापित करना चाहते हैं। कृपया * संपादित करें * प्रश्न संपादित करें और वांछित परिणाम प्रदान करें जब प्रदान किए गए XML दस्तावेज़ पर परिवर्तन लागू किया गया हो। –

उत्तर

7

यह कुंजी का उपयोग करने के लिए और अधिक कुशल हो सकता है। आप अपने टेम्पलेट्स के बाहर एक शीर्ष स्तर तत्व का उपयोग एक कुंजी निर्धारित

<xsl:key name="langByCode" match="lang" use="@id" /> 

फिर पाश में आप बस कह सकते हैं

<xsl:when test="@lang"> <!-- then i test if the attr exists --> 
    <xsl:value-of select="key('langByCode', @lang)" /> 
</xsl:when> 

लेकिन आम तौर पर पूरी बात करने के लिए एक और अधिक प्राकृतिक XSLT दृष्टिकोण बोल होगा जगह में

<xsl:template match="item[@lang]"> 
    <xsl:value-of select="key('langByCode', @lang)" /> 
</xsl:template> 

<xsl:template match="item"> 
    <xsl:text>No language set</xsl:text> 
</xsl:template> 
इन टेम्पलेट्स के साथ

आप तोकर सकते हैं: टेम्पलेट मिलान के बजाय for-each और if का उपयोग 210 और यह स्वचालित रूप से प्रत्येक आइटम के लिए उपयुक्त टेम्पलेट उठाएगा। नियम यह है कि यह सबसे विशिष्ट टेम्पलेट का उपयोग करेगा, इसलिए item[@lang] उन वस्तुओं के लिए lang विशेषता और सादा item उन लोगों के लिए है जो नहीं करते हैं।

एक तीसरा संभावना/किसी और एक भी XPath अभिव्यक्ति में जाँच करता है, तो एक छोटे से चाल मैं अतः पूरे डाल करने पर पता चला है

<xsl:value-of select=" 
    substring(
    concat('No language set', key('langByCode', @lang)), 
    1 + (15 * boolean(@lang)) 
)" /> 

ट्रिक है कि यहाँ boolean(@lang)1 अगर है जब एक नंबर रूप में व्यवहार किया है लैंग विशेषता मौजूद है और 0 यदि यह नहीं है। यदि lang="EN" है, तो कहें, फिर हम एक स्ट्रिंग "No language setEnglish" बनाते हैं और फिर 16 वें चरित्र से शुरू होने वाली सबस्ट्रिंग लेते हैं, जो "English" है। यदि नहीं लैंग विशेषता हम स्ट्रिंग "No language set" (क्योंकि एक खाली नोड सेट का स्ट्रिंग मान खाली स्ट्रिंग है) का निर्माण करते हैं और पहले वर्ण (यानी पूरी स्ट्रिंग) से शुरू होने वाली सबस्ट्रिंग लेते हैं।

आप अन्य विशेषताओं के साथ एक ही चाल का उपयोग कर सकते हैं, उदा। हम एक वैकल्पिक रंग विशेषता थी और "No color specified" यदि यह अनुपस्थित है, आप कर सकते हैं कि

<xsl:value-of select="substring(
    concat('No color specified', @color), 
    1 + (18 * boolean(@color)) 
)" /> 
+0

धन्यवाद, मैं का उपयोग करने का प्रयास करता हूं लेकिन जब मैं ऐसा करता हूं तो पेज लोड नहीं होता है। मुझ से ऐसी कौनसी गलती हो जाएगी? – carlo

+0

carlo

+0

से को स्थानांतरित करके समस्या हल करें अब के लिए अतिरिक्त वैकल्पिक विशेषता होने पर मैं क्या कर सकता हूं, चलो 'रंग' कहें? – carlo

0

एक अन्य विकल्प के साथ, अगर आप XSLT 3.0 का उपयोग कर सकें, एक map (एक और उपयोगी लिंक है कहना चाहता मान लें कि: map)।

एक्सएमएल इनपुट

<root> 
    <languages> 
     <lang id="EN">English</lang> 
     <lang id="FR">French</lang> 
     <lang id="DE">German</lang> 
    </languages> 
    <items> 
     <item lang="EN">test 1</item> 
     <item>test 2</item> 
     <item lang="FR">item 3</item> 
    </items> 
</root> 

XSLT 3,0

<xsl:stylesheet version="3.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:map="http://www.w3.org/2005/xpath-functions/map" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" extension-element-prefixes="xs map"> 
    <xsl:output indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:variable name="lang-map" as="map(xs:string, xs:string)" 
     select="map:new(
     for $lang in /*/languages/lang 
     return 
      map{$lang/@id := $lang/string()} 
     )"/> 

    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="languages"/> 

    <xsl:template match="item[@lang and map:contains($lang-map,@lang)]"> 
     <item><xsl:value-of select="$lang-map(current()/@lang)"/></item> 
    </xsl:template> 

    <xsl:template match="item"> 
     <item>No language found.</item> 
    </xsl:template> 

</xsl:stylesheet> 

आउटपुट

<root> 
    <items> 
     <item>English</item> 
     <item>No language found.</item> 
     <item>French</item> 
    </items> 
</root> 
संबंधित मुद्दे