Muthukumar
Muthukumar

Reputation: 1

how to i get the tokenize spliting function content order instead of xml order

When i use XSLT 2.0 key and tokenize function, it's return items order getting changed based on key value. in our output we required retain the same order of tokenize sequence.

Input File

<?xml version="1.0" encoding="UTF-8"?>     <a>     <bd id="a">a</bd>     <bd id="b">b</bd>     <bd id="e">e</bd>     <bd id="d">d</bd>     </a>

XSLT

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

     <xsl:key name="idcollect" match="*[@id]" use="@id" />
     <xsl:variable name="name" select="'d,b,e,a'"/>
    
     <xsl:template match="/">
      <xsl:for-each select="key('idcollect',tokenize($name,','))" >
         <xsl:copy-of select="."/>
     </xsl:for-each>
     </xsl:template>
    
</xsl:stylesheet>

current Output

<?xml version="1.0" encoding="UTF-8"?><bd id="a">a</bd><bd id="b">b</bd><bd id="e">e</bd><bd id="d">d</bd>

Expected output

<?xml version="1.0" encoding="UTF-8"?><bd id="d">d</bd><bd id="b">b</bd><bd id="e">e</bd><bd id="a">a</bd>

Upvotes: 0

Views: 41

Answers (2)

michael.hor257k
michael.hor257k

Reputation: 117140

Try:

XSLT 2.0

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

<xsl:key name="idcollect" match="*[@id]" use="@id" />
<xsl:variable name="name" select="'d,b,e,a'"/>

<xsl:template match="/">
    <xsl:variable name="ids" select="tokenize($name,',')"/>
    <xsl:for-each select="key('idcollect', $ids)" >
        <xsl:sort select="index-of($ids, .)"/>
         <xsl:copy-of select="."/>
     </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

Or, if you prefer:

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

<xsl:key name="idcollect" match="*[@id]" use="@id" />
<xsl:variable name="name" select="'d,b,e,a'"/>

<xsl:template match="/">
    <xsl:variable name="xml" select="/"/>
    <xsl:for-each select="tokenize($name, ',')" >
        <xsl:copy-of select="key('idcollect', ., $xml)"/>
     </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

Upvotes: 0

Martin Honnen
Martin Honnen

Reputation: 167716

I think you want e.g.

  <xsl:variable name="main-doc" select="/"/>
  <xsl:for-each select="for $token in tokenize($name,',') return key('idcollect', $token, $main-doc)">
     <xsl:copy-of select="."/>
 </xsl:for-each>

or in XSLT 3

  <xsl:variable name="main-doc" select="/"/>
  <xsl:for-each select="tokenize($name,',') ! key('idcollect', ., $main-doc)">
     <xsl:copy-of select="."/>
 </xsl:for-each>

Of course in both cases the for-each/copy-of nesting is not needed and e.g.

 <xsl:copy-of select="let $main-doc := / return tokenize($name,',') ! key('idcollect', ., $main-doc)"/>

or

 <xsl:variable name="main-doc" select="/"/>
 <xsl:copy-of select="for $token in tokenize($name,',') return key('idcollect', $token, $main-doc)"/>

would suffice.

Upvotes: 1

Related Questions