我有一个具有复杂层次结构的XML文件,我将其与文档fileName.xml
一起复制。我想在其他元素中插入一个新元素。目标元素基于带concat('b_',$id)
的输入文件计算。
例如 fileName.xml :
<root>
<transform id="b_0">
<transform id="b_1">
<transform id="b_2">
<transform id="b_3"/>
<transform id="b_4"/>
</transform>
</transform>
</transform>
</root>
这是结果文档的示例:
<root>
<transform id="b_0">
<transform id="obj_1"/>
<transform id="b_1">
<transform id="b_2">
<transform id="b_3">
<transform id="obj_2"/>
</transform>
<transform id="b_4"/>
</transform>
</transform>
</transform>
</root>
我的xslt代码模式:
<xsl:variable name="transforms" select="document('fileName.xml')"/>
<xsl:variable name="table" select="."/>
<xsl:template match="tr">
<xsl:variable name="param" select="$table//tr/td[2]"/>
<xsl:variable name="id" select="concat('b_',$param)"/>
<xsl:copy-of select="$transforms"/>
<xsl:copy>
<Transform>
<xsl:attribute name="id"><xsl:value-of select="concat('obj_', position())"/></xsl:attribute>
<xsl:apply-templates select="$transforms/transform[@id = $id]"/>
</Transform>
</xsl:copy>
</xsl:template>
答案 0 :(得分:0)
首先,很难理解你想要实现的目标,你没有向变换显示输入(尽管从标签名称“table”,“tr”,“td”,I'我猜一个html格式的表格。)
您似乎对某些xslt概念感到困惑:
xsl:copy-of
- 标记将节点集(在您的情况下:$transforms
- 变量的内容)复制到输出xsl:copy
- 标记将当前标记(在您的情况下为tr
- 标记,因为这是模板匹配的内容)复制到输出另外,请注意:
position()
将返回当前节点(您的tr
)在其父级内的相对位置,也许这就是您想要的,也许不是$transforms/transform[@id=$id]
仅匹配transform
顶层的$transforms
个元素。如果要匹配任何级别的元素,请使用双斜杠//
。现在,为了转换您指定的$transform
- 变量的内容,在您指定的元素中插入新元素,您必须创建:
由于您要查找的标记是动态的,基于$id
- 变量,因此必须将其作为参数传递。根据你的代码,我想你想在@id=$id
元素中插入一个新元素作为以下兄弟。
您可以使用以下方法创建此类转换:
<xsl:template match="node()" mode="tx">
<!-- parameters controlling behaviour as input -->
<xsl:param name="id" />
<xsl:param name="pos" />
<!-- copies the current node -->
<xsl:copy>
<!-- copies attributes of the current node -->
<xsl:copy-of select="@*" />
<!-- if the next sibling with tag transform has id=$id, insert a new element -->
<xsl:if test="following-sibling::transform[position()=1 and @id=$id]">
<transform>
<xsl:attribute name="id">
<xsl:value-of select="concat('obj_', $pos)" />
</xsl:attribute>
</transform>
</xsl:if>
<!-- call recursively, make sure to include the parameters -->
<xsl:apply-templates select="node()" mode="tx">
<xsl:with-param name="id" select="$id"/>
<xsl:with-param name="pos" select="$pos" />
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
请注意,我在此变换上设置mode
以便能够控制何时调用它(我只是希望在特定情况下调用它,而不是在所有输入上调用)。
这可以通过变换匹配tr调用,如下所示:
<xsl:template match="tr">
<xsl:variable name="param" select="$table//tr/td[2]" />
<xsl:variable name="id" select="concat('b_',$param)" />
<xsl:apply-templates select="$transforms" mode="tx">
<xsl:with-param name="id" select="$id"/>
<xsl:with-param name="pos" select="position()" />
</xsl:apply-templates>
</xsl:template>
此处提供了一个完整的示例:http://xsltransform.net/bwdwsA/1