开发者

one xslt to rule them all

开发者 https://www.devze.com 2023-02-03 13:18 出处:网络
So here is my problem... I have 2 xsl transformations and they both have xsl:for-each in them as a starting point.

So here is my problem...

I have 2 xsl transformations and they both have xsl:for-each in them as a starting point.

I need to create one (master) xslt which will call them. But of course, there is a catch.

This new xslt should give output one node from first xslt, then one node from second.(both xslt have EmployeeId, but are basically different reports that have to be printed one after another).

Because these existing xslt's have for-each in them, when I inc开发者_JAVA百科lude them in this master xslt I get an output: all nodes from first xslt, then all nodes from second.

Also this 2 xslt's have to be backward compatible, so they should work as before if they are not called from this master template.

I'm a starter to xslt and I managed to create some reports when working with only one xslt,but I can't seem to find the solution to this problem, so I appreciate all the help I can get.

I was thinking of creating a new xslt that would be a mix of two that I have, but this was ruled out by my boss.

Thanks, Benxy

EDIT:

Here goes some examples as requested:

This is the first xslt:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" version="4.0" encoding="windows-1250" indent="yes" omit-xml-declaration="yes" />
<xsl:template match="/" name="testXslt1">
    <xsl:for-each select="a">   
        <table>
            <tr>
                <td>
                    <xsl:value-of select="@SomeData"></xsl:value-of>
                </td>
                etc.            
            </tr>
            <xsl:apply-templates select="b" mode="tmp"/> 
        </table>
    </xsl:for-each>
</xsl:template>

<xsl:template match="node()" mode="tmp">
    <tr >
        <td><xsl:value-of select="@SomeOtherData"></xsl:value-of></td>
        etc.
    </tr>
</xsl:template>

Second xslt is similar to first one.

In Master xslt I would import both of them and in for each call templates testXslt1 and testXslt2.


This new xslt should give output one node from first xslt, then one node from second

Here is a simple example how this can be done:

This transformation combines the results of two templates that are applied on the XML document.

The first templates produces twice the value of every /*/* node. The second transformation produces the square of the value of every /*/* node. The results of applying the two remplates each on the XML document are mixed together in alternation as required, and this is the final result:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common"
 >
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/">
  <xsl:variable name="vrtfResults1">
    <xsl:apply-templates select="/"
         mode="transform1"/>
  </xsl:variable>
  <xsl:variable name="vrtfResults2">
    <xsl:apply-templates select="/"
         mode="transform2"/>
  </xsl:variable>

  <xsl:variable name="vResults1"
   select="ext:node-set($vrtfResults1)/node()"/>

  <xsl:variable name="vResults2"
   select="ext:node-set($vrtfResults2)/node()"/>

   <xsl:for-each select="$vResults1">
     <xsl:variable name="vPos" select="position()"/>

     <xsl:copy-of select=".|$vResults2[$vPos]"/>
   </xsl:for-each>

   <xsl:if test=
     "count($vResults2) > count($vResults2)">
     <xsl:copy-of select=
      "$vResults2[position()>count($vResults1)]"/>
   </xsl:if>
 </xsl:template>

 <xsl:template match="/" mode="transform1">
   <xsl:for-each select="/*/*">
    <xsl:copy>
     <xsl:value-of select=".+."/>
    </xsl:copy>
   </xsl:for-each>
 </xsl:template>

 <xsl:template match="/" mode="transform2">
   <xsl:for-each select="/*/*">
    <xsl:copy>
     <xsl:value-of select=".*."/>
    </xsl:copy>
   </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

When this transformation is applied on this XML document:

<nums>
  <num>01</num>
  <num>02</num>
  <num>03</num>
  <num>04</num>
  <num>05</num>
  <num>06</num>
  <num>07</num>
  <num>08</num>
  <num>09</num>
  <num>10</num>
</nums>

the wanted, correct result is produced:

<num>2</num>
<num>1</num>
<num>4</num>
<num>4</num>
<num>6</num>
<num>9</num>
<num>8</num>
<num>16</num>
<num>10</num>
<num>25</num>
<num>12</num>
<num>36</num>
<num>14</num>
<num>49</num>
<num>16</num>
<num>64</num>
<num>18</num>
<num>81</num>
<num>20</num>
<num>100</num>
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号