2016-05-10 49 views
1

我正在将TEI XML转换为XHTML。只有当它存在于当前节点时,我需要将xml:lang属性转换为lang属性。我尝试了一些笨拙的东西,如:如何只包含@xml: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

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

<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> 
+0

谢谢,实际上,我认为这个解决方案比来自@TimC的解决方案更清洁,但是这个解决方案不起作用。如果我使用进口产品,有什么具体的地方需要注意吗?还是它具有较低的优先级? –

+0

哦,我看到它的作品**与@TimC的答案!这意味着这两个答案是解决方案。 –

+0

命令'@ * | node()'是否重要?或者也有可能'node()| @ *'? –

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不存在,没有被选中,并且没有属性被创建。

+0

正如我写了下面的答案从@ har07,他和你的回答在某种程度上一起工作。我认为这已经解决,但真的不知道谁是赢家。 –

+1

随意接受@ har07的回答,那很好。他发现了我错过的关键点。 –

相关问题