XSLT调用多个模板

时间:2016-11-02 17:38:43

标签: xml xslt

我有一个XSLT样式表,其中包含多个单独工作的模板,但我很难将它们组合在一起。似乎我可以调用PAR模板或TABLE模板,但不能同时调用两者。我怎么能把它们放在一起?

这是XML:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="AllTogether.xslt"?>
<document>
    <item name="Some bullets">
        <richtext>
            <pardef/>
            <par def="20">
                <run>This is the </run>
                <run><font style="underline"/>preamble.</run>
            </par>
            <pardef id="21" list="bullet"/>
            <par def="21">
                <run>This is the </run>
                <run>first bullet.</run>
            </par>
            <par def="20">
                <run/>
            </par>
            <par def="21">
                <run>This is the second </run>
                <run>bullet.</run>
            </par>
            <par def="20">
                <run>This is the </run>
                <run>conclusion.</run>
            </par>
        </richtext>
    </item>
    <item name="A table">
        <richtext>
            <table>
                <tablerow>
                    <tablecell>
                        <par def="43"><run>Total Savings ($M)</run></par></tablecell>
                    <tablecell>
                        <pardef/>
                        <par def="50"><run></run></par></tablecell>
                    <tablecell>
                        <par def="44"><run>0.9360</run></par></tablecell>
                    <tablecell>
                        <par def="45"><run>5.0047</run></par></tablecell>
                    <tablecell>
                        <par def="46"><run>8.8080</run></par></tablecell></tablerow></table>
        </richtext>
    </item>
</document>

这是所需的输出:

<html>
  <head/>
  <body>
     <table border="1">
        <tbody>
           <tr>
              <td>Some bullets</td>
              <td>
                 <p>This is the <span style="text-decoration: underline;">preamble.</span></p><ul>
                 <li>This is the first bullet.</li></ul>
                 <p></p><ul>
                 <li>This is the second bullet.</li></ul>
                 <p>This is the conclusion.</p>
              </td>
           </tr>
           <tr>
              <td>A table</td>
              <td>
                 <table border="1">
                    <tr>
                       <td>Total Savings ($M)</td>
                       <td></td>
                       <td>0.9360</td>
                       <td>5.0047</td>
                       <td>8.8080</td>
                    </tr>
                 </table>
              </td>
           </tr>
        </tbody>
     </table>
  </body>

这是样式表:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
   <xsl:output indent="yes" method="html"/>
   <xsl:template match="/*">
        <html>
            <body>
                <table border="1">
                    <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="table">
        <table border="1">
            <xsl:for-each select="tablerow">
                <tr>

                    <xsl:for-each select="tablecell">
                        <td>
                            <xsl:apply-templates />
                        </td>
                    </xsl:for-each>


                </tr>
            </xsl:for-each>

        </table>      
    </xsl:template>

    <xsl:template match="richtext/par">
        <xsl:for-each-group select="par[run[normalize-space()]]" group-adjacent="if (@def) then @def else preceding-sibling::par[run[normalize-space()]][@def][1]/@def">
            <xsl:variable name="listType" select="preceding-sibling::*[1][self::pardef]/@list" />
            <xsl:choose>
                <xsl:when test="$listType = 'unordered'">    
                    <ul>
                        <xsl:apply-templates select="current-group()" mode="list"/>
                    </ul>
                </xsl:when>
                <xsl:when test="$listType = 'ordered'">    
                    <ol>
                        <xsl:apply-templates select="current-group()"  mode="list"/>
                    </ol>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:apply-templates select="current-group()" mode="para" />   
                </xsl:otherwise>     
            </xsl:choose>   
        </xsl:for-each-group>
    </xsl:template>

    <xsl:template match="par" mode="list">
        <li>
            <xsl:value-of select="run" separator=""/>
        </li>  
    </xsl:template>

    <xsl:template match="par" mode="para">
        <p>
            <xsl:value-of select="run" separator=""/>
        </p>  
    </xsl:template>

    <xsl:template match="run">
        <xsl:choose>
            <xsl:when test="font[@style = 'underline']">
                <span style="text-decoration: underline;">
                    <xsl:value-of select="." separator=""/>
                </span>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="text()" separator=""/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

</xsl:stylesheet>

1 个答案:

答案 0 :(得分:1)

此模板中出现问题...

<xsl:template match="richtext/par">

在其中<xsl:for-each-group select="par",但由于您已经定位在par元素上,因此会尝试选择其中的子par元素,其中没有元素。< / p>

解决方案是将模板更改为匹配richtext,如下所示:

 <xsl:template match="richtext[par]">

这样,您只匹配具有子richtext元素的par元素,因此它不会将richtext元素与子table匹配,允许其他模板仍然匹配。