如果@xml:lang属性存在,如何包含它?

时间:2016-05-10 12:36:45

标签: xml xslt

我正在将TEI XML转换为XHTML。只有当前节点存在时,我才需要将xml:lang属性转换为lang属性。我尝试了一些有点笨拙的事情:

<xsl:template match="tei:p">
    <xsl:element name="p">
        <xsl:attribute name="lang">
            <xsl:value-of select="./@xml:lang"/>
        </xsl:attribute>
        <xsl:apply-templates/>
    </xsl:element>
</xsl:template>

......但我想坚持最佳做法。如何简单地获取xml:lang属性并将其转换为lang属性?当然,如果它不存在,请不要使用它。

我已将着名的身份规则添加到我的模板(此处为according to Michael Kay),但它没有做任何事情:

<!-- Identity Rule -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*" />
    </xsl:copy>
</xsl:template>
<xsl:template match="@xml:lang">
    <xsl:attribute name="lang">
        <xsl:value-of select="."/>
    </xsl:attribute> 
</xsl:template>

我想我不理解这条规则。

我想将它用于任何标记,例如:

<p xml:lang="en">
    <seg xml:lang="fr">XYZ</seg> otherwise English.
</p>

预期产出:

<p lang="en">
    <seg lang="fr">XYZ</seg> otherwise English.
</p>

2 个答案:

答案 0 :(得分:2)

如果您有一个匹配tei:p的现有模板,那么这将优先于身份模板。您当前的模板<xsl:apply-templates />,但这相当于<xsl:apply-templates select="node()" />。它不是处理属性。

您需要做的是将当前xsl:attributes替换为xsl:apply-templates,而是选择@xml:lang属性,允许相关模板与之匹配。

<xsl:template match="tei:p">
    <p>
        <xsl:apply-templates select="./@xml:lang"/>
        <xsl:apply-templates/>
    </p>
</xsl:template>

因此,如果@xml:lang不存在,则不会选择任何内容,也不会创建任何属性。

答案 1 :(得分:2)

您的身份模板也应该处理子节点,否则它将停在第一个匹配的节点上:

<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
</xsl:template>
<xsl:template match="@xml:lang">
    <xsl:attribute name="lang">
        <xsl:value-of select="."/>
    </xsl:attribute> 
</xsl:template>