使用Identity转换添加XML节点,然后在不同的模板中输出到xhtml

时间:2014-11-21 15:15:04

标签: xml xslt xslt-1.0

我不确定我要求的是否可行,但我需要首先将两个节点添加到父XML节点中,然后使用不同的模板以xhtml输出整个批次。我不知道如何将转换结果输入第二个模板。我对XSL并不陌生,但我是身份转换的新手,所以这可能高于我的工资等级。

以下是这个例子。

我有:

<metadata>
    <app><name>a</name></app>
    <app><name>b</name></app>
    <app><name>c</name></app>
</metadata>

我需要在<app>中再插入2个<metadata>个节点,到目前为止我已经使用过了:

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

<xsl:template match="metadata/app">
    <metadata>
        <xsl:copy-of select="."/>
        <app><name>d</name></app>
        <app><name>e</name></app>
    <metadata>
</xsl:template>

添加了2个新的<app>节点后,我需要使用另一个模板将新转换的<metadata>输出为html。我想我可以使用:

<xsl:apply-templates select="app"><xsl:sort select="app/name" /></xsl:apply-templates>

我在这里使用模板来对节点进行排序,但导致它并不总是确定应用程序/名称节点是按字母顺序排列的。

<xsl:template match="app">
    <h1><xsl:value-of select="name"/></h1>
    ...
</xsl:template>

...但我不知道在哪里或如何使用apply-templates正确地将新<metadata>放入最后一个模板中。在此先感谢您的帮助。

编辑所需的最终html输出(非常简单):

<h1>a</h1>
<h1>b</h1>
<h1>c</h1>
<h1>d</h1>
<h1>e</h1>

3 个答案:

答案 0 :(得分:0)

如果要在一个XSLT 1.0样式表中执行两个转换步骤,则需要在变量上使用exsl:node-set或类似步骤,您可能需要使用模式。

所以定义一个全局变量

<xsl:variable name="result1">
  <xsl:apply-templates select="metadata"/>
</xsl:variable>

然后你可以使用

<xsl:template match="/">
  <xsl:apply-templates select="exsl:node-set($result1)/app"/>
</xsl:template>

<xsl:template match="app">
    <h1><xsl:value-of select="name"/></h1>
    ...
</xsl:template>

这个简单的示例不需要模式,但只要您想为两个步骤的相同匹配模式编写模板,就需要使用模式来区分它们。

答案 1 :(得分:0)

尝试添加

<xsl:output method="xml" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" doctype-public="-//W3C//DTD XHTML 1.0 Transitional//
EN" indent="yes"/>

答案 2 :(得分:0)

你真的需要在这里进行两次转换吗?在不确切知道您要实现的目标的情况下,作为建议,您可以将app匹配模板更改为也是命名模板,并接受默认为name的参数

<xsl:template match="app" name="outputApp">
    <xsl:param name="displayName" select="name" />
    <h1><xsl:value-of select="$displayName"/></h1>
    ...
</xsl:template>

然后,不要创建新的app元素,只需使用name参数的覆盖值调用命名模板,就像这样

    <xsl:apply-templates select="app">
        <xsl:sort select="app/name" />
    </xsl:apply-templates>
    <xsl:call-template name="outputApp">
        <xsl:with-param name="displayName" select="'d'" />
    </xsl:call-template>
    <xsl:call-template name="outputApp">
        <xsl:with-param name="displayName" select="'e'" />
    </xsl:call-template>