我想知道下面的XSLT(1.0)是否可以。我有一个XML模式,它定义了一个元素a
,其中可能包含元素b
、c
等。然而,a
可能递归地出现在a
中。
我为a
, b
等提供模板
<xsl:template match="/">
<xsl:for-each select="a">
<!-- matches also a nested <a>-->
<xsl:apply-templates/>
<!-- matches only nested <a> (this has already been matched before) -->
<xsl:for-each select="a">
<xsl:apply-templates/>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
<!-- for nested <a> -->
<xsl:template match="a">
<!-- do some stuff here -->
</xsl:template>
<xsl:template match="b">
<!-- do some stuff here -->
</xsl:template>
<xsl:template match="c">
<!-- do some stuff here -->
</xsl:template>
给定以下XML, a
中的每个a
被处理两次:
<a>
<b> .... </b>
<a><b> ... </b></a>
</a>
像这样,我可以在a
之后添加一个嵌套的a
:
<a>
<b> .... </b>
</a>
<a><b> ... </b></a>
我想知道这是有效的XSLT 1.0和预期的行为,还是应该被其他东西取代的hack。
在典型情况下(有许多例外),您将递归地处理节点,从根到叶遍历树。那么你的样式表的结构应该是:
<xsl:template match="a">
<!-- do some stuff here -->
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="b">
<!-- do some stuff here -->
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="c">
<!-- do some stuff here -->
</xsl:template>
为了以不同的方式处理根a
,您可以这样做:
<xsl:template match="/a">
<!-- do some stuff here -->
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="a">
<!-- do some other stuff here -->
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="b">
<!-- do some stuff here -->
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="c">
<!-- do some stuff here -->
</xsl:template>
参见:https://www.w3.org/TR/xslt/#section-Processing-Model
补充道:
要执行在您编辑的问题中显示的转换-即移动a
元素是根a
元素的子元素,并使它们成为根元素的兄弟元素,您可以这样做:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/a">
<xsl:copy>
<xsl:apply-templates select="b"/>
</xsl:copy>
<xsl:apply-templates select="a"/>
</xsl:template>
</xsl:stylesheet>
然而,结果是:
<a>
<b> .... </b>
</a>
<a>
<b> ... </b>
</a>
有两个根元素,因此不是一个格式良好的XML文档。