0
votes

I have an xsl:template that has two flavours, depending on the value in an attribute. I need to invoke this template multiple times, each time filtering on a different tag.

I have the following XML:

<?xml version="1.0" encoding="UTF-8"?>
<document>
    <item name="Recommendations">
        <richtext>
            <pardef/>
            <par><run>This is the </run><run>preamble.</run></par>
            <pardef list='bullet'/>
            <par><run>This is the </run><run>first bullet.</run></par>
            <par><run>This is the second </run><run>bullet.</run></par>
        </richtext>
    </item>
    <item name="Comments">
        <richtext>
            <pardef/>
            <par><run>This is the </run><run>preamble.</run></par>
            <pardef list='bullet'/>
            <par><run>This is the </run><run>first bullet.</run></par>
            <par><run>This is the second </run><run>bullet.</run></par>
        </richtext>
    </item>
</document>

Thanks to the solution that @uL1 posted here, I have the following XSLT:

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

<xsl:output indent="yes"/>
<xsl:key name="key-for-par" match="document/item/richtext/par" use="generate-id(preceding-sibling::pardef[1])"/>

<xsl:template match="/">
<html>
    <body>
        <table>
            <tr>
                <td>Recommendations</td>
                <td>
                    <xsl:apply-templates select="pardef[@list = 'bullet']"/>
                    <xsl:apply-templates select="pardef[not(@list)]"/>
                </td>
            </tr>
            <tr>
                <td>Comments</td>
                <td>
                    <xsl:apply-templates select="pardef[@list = 'bullet']"/>
                    <xsl:apply-templates select="pardef[not(@list)]"/>
                </td>
            </tr>
        </table>
    </body>
</html>
</xsl:template>

<xsl:template match="pardef[@list = 'bullet']">
    <ul>
        <xsl:for-each select="key('key-for-par', generate-id(.))">
        <li>
        <xsl:value-of select="run" separator=""/>
        </li>
        </xsl:for-each>
    </ul>
</xsl:template>

    <xsl:template match="pardef[not(@list)]">
        <p>
            <xsl:for-each select="key('key-for-par', generate-id(.))">
                    <xsl:value-of select="run" separator=""/>
            </xsl:for-each>
        </p>
    </xsl:template>

</xsl:stylesheet>
1

1 Answers

0
votes

I think the biggest problem is that you're doing an apply-templates selecting pardef, but your context is /.

This is what I would do (it's just a guess though since you didn't show what your desired output should be)...

XML Input

<document>
    <item name="Recommendations">
        <richtext>
            <pardef/>
            <par><run>This is the </run><run>preamble.</run></par>
            <pardef list='bullet'/>
            <par><run>This is the </run><run>first bullet.</run></par>
            <par><run>This is the second </run><run>bullet.</run></par>
        </richtext>
    </item>
    <item name="Comments">
        <richtext>
            <pardef/>
            <par><run>This is the </run><run>preamble.</run></par>
            <pardef list='bullet'/>
            <par><run>This is the </run><run>first bullet.</run></par>
            <par><run>This is the second </run><run>bullet.</run></par>
        </richtext>
    </item>
</document>

XSLT 2.0

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
  <xsl:strip-space elements="*"/>
  <xsl:output indent="yes"/>

  <xsl:key name="key-for-par" match="par" 
    use="generate-id(preceding-sibling::pardef[1])"/>

  <xsl:template match="/*">
    <html>
      <body>
        <table>
          <tbody>
            <xsl:apply-templates/>
          </tbody>
        </table>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="item">
    <tr>
      <td><xsl:value-of select="@name"/></td>
      <td>
        <xsl:apply-templates/>
      </td>
    </tr>
  </xsl:template>

  <xsl:template match="pardef[@list = 'bullet']">
    <ul>
      <xsl:for-each select="key('key-for-par', generate-id())">
        <li>
          <xsl:value-of select="run" separator=""/>
        </li>
      </xsl:for-each>
    </ul>
  </xsl:template>

  <xsl:template match="pardef[not(@list)]">
    <p>
      <xsl:for-each select="key('key-for-par', generate-id())">
        <xsl:value-of select="run" separator=""/>
      </xsl:for-each>
    </p>
  </xsl:template>

  <xsl:template match="run">
    <!--"run" is being pulled. suppress output when pushed.-->
  </xsl:template>

</xsl:stylesheet>

Output

<html>
   <body>
      <table>
         <tbody>
            <tr>
               <td>Recommendations</td>
               <td>
                  <p>This is the preamble.</p>
                  <ul>
                     <li>This is the first bullet.</li>
                     <li>This is the second bullet.</li>
                  </ul>
               </td>
            </tr>
            <tr>
               <td>Comments</td>
               <td>
                  <p>This is the preamble.</p>
                  <ul>
                     <li>This is the first bullet.</li>
                     <li>This is the second bullet.</li>
                  </ul>
               </td>
            </tr>
         </tbody>
      </table>
   </body>
</html>