在转换中双重使用<xsl:apply-templates select =“@ * | node()”>

时间:2016-05-09 14:41:02

标签: xslt

我有一个像(简化版)那样的变换:

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

    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="no"/>

    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

     <xsl:template match="head">
        <xsl:element name="head">
            <xsl:element name="title">
                <xsl:text>Transformed document</xsl:text>
            </xsl:element>
        </xsl:element>
     </xsl:template>

    <xsl:template match="body">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet> 

它转换示例HTML文档

<?xml version="1.0" encoding="iso-8859-1"?>
<html xml:lang="en" lang="en">
    <head>
        <title>Sample page</title>
        <link rel="stylesheet" href="/style.css" type="text/css"/>
        <meta name="author" content="John Doe"></meta>
    </head>
    <body>
        <h1>Header</h1>
        <p>Some text</p>
        <p>Some other text</p>
    </body>
</html>

致:

<?xml version="1.0" encoding="UTF-8"?><html lang="en" xml:lang="en">
    <head><title>Transformed document</title></head>
    <body>
        <h1>Header</h1>
        <p>Some text</p>
        <p>Some other text</p>
    </body>
</html>

我无法理解为什么我需要两次调用apply-templates。据我所知,第一个应该将所有内容复制到输出(包括头部,应该被覆盖),第二个应该只复制主体(这是我想要的)。但是,两者似乎都是必要的。如果我从正文中删除它,我只有输出头,如果我删除第一个,我只从节点中提取文本,而不是节点。

为什么在以下示例中<xsl:apply-templates select="@* | node()"/>需要两次,是否可以简化该示例?

1 个答案:

答案 0 :(得分:1)

这里的问题是两次调用xsl:apply-templates,但整个模板都是多余的。

由于您未以任何方式更改body,因此可以让它由身份转换模板(您的第一个模板)处理,并删除最后一个模板:

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

    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="no"/>

    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

     <xsl:template match="head">
        <xsl:element name="head">
            <xsl:element name="title">
                <xsl:text>Transformed document</xsl:text>
            </xsl:element>
        </xsl:element>
     </xsl:template>

</xsl:stylesheet> 

顺便说一句,您还可以将模板匹配head简化为:

<xsl:template match="head">
    <head>
        <title>Transformed document</title>
    </head>
</xsl:template>

如果事先知道元素的名称,则无需使用xsl:element