为什么不处理属性模板

时间:2015-12-15 08:58:21

标签: xml xslt xpath

我想要实现的是,当处理器在属性节点处将其值包装到att元素中时。

这是xml(输入)文件:

<planet-earth>
    <europe>
        <germany president="Joachim Gauck">Berlin</germany>
        <romania>Bucharest</romania>
        <france>Paris</france>
    </europe>
    <asia>
        <japan>Tokio</japan>
        <india>Delhi</india>
        <china>Pekin</china>
    </asia>
    <america>
        <brazil>Brazil</brazil>
    </america>
    <africa>
        <egipt>Kairo</egipt>
    </africa>
</planet-earth>

这是样式表:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml"/>
    <xsl:template match="/">
        <root>
            <xsl:apply-templates/>
        </root>
    </xsl:template>
    <xsl:template match="@*">
        <att>
            <xsl:value-of select="."/>
        </att>
    </xsl:template>
    <xsl:template match="text()"/>
</xsl:stylesheet>

这是我得到的结果:<root/>。相反,我想要这个:

<root>
  <att>Joachim Gauck</att>
</root>

为什么不处理匹配所有属性的模板?

1 个答案:

答案 0 :(得分:1)

这是因为<xsl:apply-templates/>与执行<xsl:apply-templates select="node()" />相同。它不选择属性,您需要明确执行以下操作以确保拾取模板匹配属性

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

但是,您的XSLT中没有任何匹配元素的模板。这意味着匹配元素的built-in template rule将适用,这相当于此

<xsl:template match="*|/">
  <xsl:apply-templates/>
</xsl:template>

换句话说,元素的内置模板规则不是选择属性,因此您需要一个模板

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

试试这个XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml"/>
    <xsl:template match="/">
        <root>
            <xsl:apply-templates select="@*|node()"/>
        </root>
    </xsl:template>

    <xsl:template match="@*">
        <att>
            <xsl:value-of select="."/>
        </att>
    </xsl:template>

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

    <xsl:template match="text()"/>
</xsl:stylesheet>