【问题标题】:xsl template is overriding with xsl includexsl 模板被 xsl 包含覆盖
【发布时间】:2017-11-06 23:28:30
【问题描述】:

在使用 xsl 为 xml 开发 html 页面时,我正在尝试创建一些可重用的模板。但是当我包含其他 xsl 时,主 xsl 模板被覆盖而不是添加到它。请提出建议。

这是我的 xml,

<employee>
<address>
    <street>street1</street>
    <city>city1</city>
    <doornumber>1-23</doornumber>
    <pincode>123456</pincode>
</address>
<personalinfo>
    <name>testname1</name>
    <phone>999999999</phone>
    <dob>23-09-34</dob>
</personalinfo>
<remarks>
    <education>
        <name>testname2</name>
        <college>college1</college>
        <gpa>7.5</gpa>
    </education>
</remarks>

<data>
    <name>data1</name>
</data>
<data>
    <name>data2</name>
</data>
<data>
    <name>data3</name>
</data>
<data>
    <name>data4</name>
</data>
<data>
    <name>data5</name>
</data>
</employee>

这是我的主要 xsl,

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

<xsl:template match="/">
    <html>
        <body>    
            <table>
                <tr>
                    <th>Name</th>
                    <th>College</th>
                    <th>City</th>
                </tr>
                <xsl:apply-templates/>
            </table>
        </body>
    </html>
</xsl:template>

<xsl:template match="employee">
    <tr>
        <td>
            <xsl:value-of select="personalinfo/name"/>
        </td>
        <td>
            <xsl:value-of select="remarks/education/college"/>
        </td>
        <td>
            <xsl:value-of select="address/city"/>
        </td>
    </tr>
</xsl:template>
<!-- <xsl:include href="test_include1.xsl" /> -->
<!-- <xsl:include href="test_include2.xsl" /> -->
</xsl:stylesheet>

这是我的 test_include1.xsl,

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

<xsl:template match="employee">

<table><tr>
    <th>data names</th></tr>
<xsl:for-each select="data">
<tr>
    <td>
        <xsl:value-of select="name"/>
    </td>
</tr>

</xsl:for-each>
</table>
</xsl:template>

</xsl:stylesheet>

这是我的 test_include2.xsl,

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

<xsl:template match="employee">

<table><tr>
                <th>Name</th>
                <th>College</th></tr>
<tr>
    <td>
        <xsl:value-of select="personalinfo/name"/>
    </td>
    <td>
        <xsl:value-of select="remarks/education/college"/>
    </td>
    </tr>
</table>
</xsl:template>
</xsl:stylesheet>

我试图在不同的模板中模块化相同的 xml 数据,以便我可以在其他样式表中重用相同的模板。请建议我如何实现这一点。谢谢你。 这是预期的结果,

     <html><body>
   <table>
        <tr>
        <th>Name</th>
        <th>College</th>
        <th>City</th>
        </tr>
        <tr>
        <td>testname1</td>
        <td>college1</td>
        <td>city1</td>
        </tr>
    </table>
    <table>
        <tr><th>data names</th></tr>
        <tr><td>data1</td></tr>
        <tr><td>data2</td></tr>
        <tr><td>data3</td></tr>
        <tr><td>data4</td></tr>
        <tr><td>data5</td></tr>
     </table>
     <table>
        <tr>
        <th>Name</th>
        <th>College</th>
        </tr>
        <tr>
        <td>testname1</td>
        <td>college1</td>
        </tr>
    </table>
    </body></html>

【问题讨论】:

  • 通过使用xsl:include,包含的模板将被简单地添加到主 XSLT,就好像它们是由您手动添加的一样。这将为您留下三个匹配employee 的模板,具有相同的优先级,这被视为错误。 (一些处理器会发出错误信号,其他处理器只会使用最后一个,就像你的情况一样)。您可能需要xsl:import,但尚不清楚您实际想要实现的目标。您可以编辑您的问题以显示您的预期输出吗?谢谢!
  • 我有一个巨大的 xml,其中不同部分的数据被创建为多个可重用的模板。当我需要它时,我应该能够将它包含到主 xsl 中。我尝试使用 xsl:import,但这也覆盖了具有相同匹配的模板。有什么方法可以合并具有相同匹配的模板而不覆盖?
  • 如果你想用不同的模板处理同一个节点然后考虑使用模式,在w3.org/TR/xslt#apply-imports中也有一些支持应用导入的模板。
  • 感谢马丁的建议。我能够通过模板模式实现这一点。如果我们在 xsl 中使用更多的模板模式(例如 10 种左右),是否会对性能产生任何影响?

标签: html xml templates xslt xslt-1.0


【解决方案1】:

首先,我没有在这些样式表中看到任何 xsl:include 声明,所以我不太确定您在做什么。 [抱歉 - 错过了淡灰色注释掉的代码 - 我的显示器对比度差。]

其次,在 XSLT 1.0 中,当您有两个模板匹配相同节点、具有相同优先级和优先级时的行为并没有很好地定义。从技术上讲,这是一个错误,但处理器可以通过选择“样式表中最后一个”的规则来恢复 - 当涉及多个模块时,该规则本身并没有特别明确的定义。

第三,你说“主 xsl 模板被覆盖而不是添加它”。这表明您对希望它的行为方式有一些特殊的期望,但我无法真正弄清楚这种期望是什么。你没有给出任何预期的结果,所以我不知道你想要达到什么目的。但是,如果您有多个与节点匹配的规则,则总是会出现错误,或者恰好执行了其中一个规则 - 它们永远不会以任何方式组合。

【讨论】:

  • 你好迈克尔,我在上面添加了预期的输出。总之,我有多个样式表。因此,尝试从同一个 xml 创建多个模板以在其他样式表中重用。我尝试使用 但没有工作,因为其他模板由于相同的匹配而被覆盖。请建议我如何实现这一目标。谢谢。
【解决方案2】:

这可以通过模式来实现。 另一种方法是给每个 xsl:template 匹配一个优先级编号。您要执行的那个应该具有最高优先级。优先级是 xsl:template 的属性

<xsl:template match = "employee" priority = "4"> do the task </xsl:template>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-08
    • 2014-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多