2010-08-28 9 views
7

मैं एक एक्सएमएल फ़ाइल में रिकॉर्ड्स का एक समूह सॉर्ट करने की कोशिश कर रहा हूं। चाल यह है कि मुझे अलग-अलग नोड्स के लिए अलग-अलग तत्वों का उपयोग करके क्रमबद्ध करने की आवश्यकता है। एक सरल उदाहरण देने के लिए, मैं ऐसा करना चाहते हैं: एक xml फ़ाइलxsl: एकाधिक तत्वों का उपयोग कर एक एक्सएमएल फ़ाइल को सॉर्ट करें

<?xml version="1.0" encoding="utf-8" ?> 

<buddies> 

<person> 
<nick>Jim</nick> 
<last>Zulkin</last> 
</person> 

<person> 
<first>Joe</first> 
<last>Bumpkin</last> 
</person> 

<person> 
<nick>Pumpkin</nick> 
</person> 

<person> 
<nick>Andy</nick> 
</person> 

</buddies> 

मैं इसे

Andy 
Joe Bumpkin 
Pumpkin 
Jim Zulkin 

है कि करने के लिए परिवर्तित करना चाहते हैं को देखते हुए एक व्यक्ति को पहले से किसी सबसेट के आधार पर सूचीबद्ध किया जा सकता है नाम, अंतिम नाम और एक निक। सॉर्टिंग कुंजी अंतिम नाम है यदि यह मौजूद है, अन्यथा यह उपनाम है यदि यह मौजूद है और अन्यथा पहला नाम है।

xsl के रूप में चर के उपयोग के बाद मुझे यहां कठिनाइयों का सामना करना पड़ रहा है: सॉर्ट कुंजियां apparently not allowed है।

मेरे वर्तमान सबसे अच्छा शॉट एक दो कदम परिवर्तन के लिए है: इस स्टाइलशीट

<?xml version="1.0" encoding="ISO-8859-1"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<xsl:output omit-xml-declaration="no" indent="yes"/> 

<!-- *** convert each person record into a person2 record w/ the sorting key *** --> 
<xsl:template match="/buddies"> 
    <buddies> 
    <xsl:for-each select="person"> 
    <person2> 
     <xsl:copy-of select="*"/> 
     <!-- add the sort-by tag --> 
     <sort-by> 
     <xsl:choose> 
      <xsl:when test="last"> <xsl:value-of select="last"/> 
      </xsl:when> 
      <xsl:otherwise> 
       <xsl:choose> 
        <xsl:when test="nick"> <xsl:value-of select="nick"/> </xsl:when> 
        <xsl:otherwise> <xsl:value-of select="first"/> </xsl:otherwise> 
       </xsl:choose> 
      </xsl:otherwise> 
     </xsl:choose> 
    </sort-by> 
    </person2> 
</xsl:for-each> 
</buddies> 

और फिर का उपयोग कर प्रत्येक रिकॉर्ड में एक विशेष टैग जोड़े जिसके परिणामस्वरूप एक्सएमएल सॉर्ट

<?xml version="1.0" encoding="ISO-8859-1"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<xsl:template match="/buddies"> 
    <xsl:apply-templates> 
     <xsl:sort select="sort-by"/> 
    </xsl:apply-templates> 
</xsl:template> 

<xsl:template match="person2"> 
    <xsl:value-of select="first"/> 
    <xsl:value-of select="nick"/> 
    <xsl:value-of select="last"/><xsl:text> 
</xsl:text> 
</xsl:template> 

हालांकि यह दो-चरणीय परिवर्तन काम करता है, मैं सोच रहा हूं कि क्या सिर्फ एक ही बार में इसे करने का अधिक शानदार तरीका है?

उत्तर

5

आप concat XPath फ़ंक्शन का उपयोग कर सकते हैं:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="text"/> 
    <xsl:template match="/buddies"> 
     <xsl:apply-templates> 
      <xsl:sort select="concat(last,nick,first)"/> 
     </xsl:apply-templates> 
    </xsl:template> 
    <xsl:template match="person"> 
     <xsl:value-of select="concat(normalize-space(concat(first, 
                  ' ', 
                  nick, 
                  ' ', 
                  last)), 
            '&#xA;')"/> 
    </xsl:template> 
</xsl:stylesheet> 
+0

धन्यवाद एक अरब! 'Fn: concat' उत्तर के लिए –

+0

+1। मैंने संपादित किया है क्योंकि आपका उत्तर आउटपुट वांछित आउटपुट नहीं है –

+1

@Zhenya: ध्यान दें कि यह पूंजीकरण में भारी निर्भर करता है। यदि आप अपने इनपुट के कारण नहीं कर सकते हैं, तो आपको स्पेस सेपरेटर कॉन्सटेनेशन का उपयोग करना चाहिए। –

1

क्या आप इस टेम्पलेट को अपेक्षित परिणाम देने का प्रयास कर सकते हैं? आपके सरल उदाहरण के लिए यह सही उत्तर देता है लेकिन वहां कोने के मामले हो सकते हैं जो काम नहीं करेंगे। यदि तत्वों में से कोई एक गायब है तो अग्रणी और पीछे की जगहों को हटाने के लिए सामान्यीकृत-स्थान का उपयोग किया जाता है।

<xsl:template match="/buddies"> 
    <xsl:for-each select="person"> 
     <xsl:sort select="normalize-space(concat(last, ' ', nick, ' ', first))"/> 

     <xsl:if test="first"> 
      <xsl:value-of select="first" /> 
      <xsl:text> </xsl:text> 
     </xsl:if> 

     <xsl:if test="nick"> 
      <xsl:value-of select="nick" /> 
      <xsl:text> </xsl:text> 
     </xsl:if> 

     <xsl:value-of select="last" /> 
     <xsl:text>&#10;</xsl:text> 
    </xsl:for-each> 
</xsl:template> 
+0

यह आसान है (और मैं अभी भी सही लगता है) यदि आप बिल्कुल नहीं प्रकार कुंजी में रिक्त स्थान का उपयोग करता है। – svick

+0

धन्यवाद() फ़ंक्शन के लिए बहुत कुछ धन्यवाद! बीटीडब्ल्यू, यह पता चला है कि svick द्वारा संस्करण, जहां रिक्त स्थान का उपयोग नहीं किया जाता है, साथ ही साथ काम करता है। –

+0

@svick यह इस मामले में सच है, लेकिन समान मामलों वाले तत्वों को शामिल करने वाले तत्वों में, एक डिलीमीटर छोड़ने से गलत क्रम हो जाएगी। – vallismortis

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