XSLT - 添加新属性和节点
XSLT - Add new attributes and node
我有一个 xml 如下,
<doc>
<a type="atr111"></a>
<a type="atr111"></a>
<a type="atr111"></a>
<a type="atr222"></a>
<a type="atr222"></a>
<a type="atr222"></a>
</doc>
我的要求是,
- 向具有属性
atr111
和atr222
的节点添加动态递增id
属性
- 在节点内添加新节点,命名为
<newNode>
具有属性 id="newAttr"
,其具有属性 atr111
和 atr222
- 将
<a>
节点属性值 atr111
更改为 atr222
。
所以我的预期输出是,
<doc>
<a id="id-1" type="atr222"><newNode id="newAttr"/></a>
<a id="id-2" type="atr222"><newNode id="newAttr"/></a>
<a id="id-3" type="atr222"><newNode id="newAttr"/></a>
<a id="id-4" type="atr222"><newNode id="newAttr"/></a>
<a id="id-5" type="atr222"><newNode id="newAttr"/></a>
<a id="id-6" type="atr222"><newNode id="newAttr"/></a>
</doc>
我为获得这些输出而编写的 xsl 如下,
<xsl:template match="a" priority="1">
<!-- add new dynamic id -->
<xsl:copy>
<xsl:attribute name="id">
<xsl:value-of select="'id-'"/>
<xsl:number count="a[@type='atr111' or @type='atr222']" level="any"/>
</xsl:attribute>
</xsl:copy>
<!-- add newNode inside <a> node -->
<xsl:copy>
<newNode>
<xsl:attribute name="id">newAttr</xsl:attribute>
</newNode>
</xsl:copy>
</xsl:template>
<!-- change existing 'atr111' attribute value to 'atr222' -->
<xsl:template match="a/@type[. = 'atr111']">
<xsl:attribute name="type">atr222</xsl:attribute>
</xsl:template>
我目前的输出结果如下,
<doc>
<a id="id-1"/><a><newNode id="newAttr"/></a>
<a id="id-2"/><a><newNode id="newAttr"/></a>
<a id="id-3"/><a><newNode id="newAttr"/></a>
<a id="id-4"/><a><newNode id="newAttr"/></a>
<a id="id-5"/><a><newNode id="newAttr"/></a>
<a id="id-6"/><a><newNode id="newAttr"/></a>
</doc>
如您所见,动态 ID 已按预期添加,并且具有新属性的 <newNode>
也有 added.but 它复制了 <a>
节点。现有属性 type
也已消失。
如何组织我的代码以获得预期的输出?
您忘记复制 type
属性。 <xsl:copy>
只复制当前节点本身,而不是它的 children 或属性。
下面利用身份模板进行复制children和属性的过程。
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output encoding="UTF-8" indent="yes" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="a[@type='atr111' or @type='atr222']">
<xsl:copy>
<xsl:attribute name="id">
<xsl:text>id-</xsl:text>
<xsl:number count="a[@type='atr111' or @type='atr222']" level="any" />
</xsl:attribute>
<xsl:apply-templates select="@*|node()" />
<newNode id="newAttr" />
</xsl:copy>
</xsl:template>
</xsl:transform>
输出:
<doc>
<a id="id-1" type="atr111"><newNode id="newAttr"/></a>
<a id="id-2" type="atr111"><newNode id="newAttr"/></a>
<a id="id-3" type="atr111"><newNode id="newAttr"/></a>
<a id="id-4" type="atr222"><newNode id="newAttr"/></a>
<a id="id-5" type="atr222"><newNode id="newAttr"/></a>
<a id="id-6" type="atr222"><newNode id="newAttr"/></a>
</doc>
如果没有其他 children,您当然也可以使用 <xsl:copy-of select="@type" />
,但这不太灵活:通过身份模板复制使您能够继承变量输入并添加,例如, 一个 <xsl:template match="a/@type">
later-on 对 @type
节点做一些特殊处理,如有必要。
我有一个 xml 如下,
<doc>
<a type="atr111"></a>
<a type="atr111"></a>
<a type="atr111"></a>
<a type="atr222"></a>
<a type="atr222"></a>
<a type="atr222"></a>
</doc>
我的要求是,
- 向具有属性
atr111
和atr222
的节点添加动态递增 - 在节点内添加新节点,命名为
<newNode>
具有属性id="newAttr"
,其具有属性atr111
和atr222
- 将
<a>
节点属性值atr111
更改为atr222
。
id
属性
所以我的预期输出是,
<doc>
<a id="id-1" type="atr222"><newNode id="newAttr"/></a>
<a id="id-2" type="atr222"><newNode id="newAttr"/></a>
<a id="id-3" type="atr222"><newNode id="newAttr"/></a>
<a id="id-4" type="atr222"><newNode id="newAttr"/></a>
<a id="id-5" type="atr222"><newNode id="newAttr"/></a>
<a id="id-6" type="atr222"><newNode id="newAttr"/></a>
</doc>
我为获得这些输出而编写的 xsl 如下,
<xsl:template match="a" priority="1">
<!-- add new dynamic id -->
<xsl:copy>
<xsl:attribute name="id">
<xsl:value-of select="'id-'"/>
<xsl:number count="a[@type='atr111' or @type='atr222']" level="any"/>
</xsl:attribute>
</xsl:copy>
<!-- add newNode inside <a> node -->
<xsl:copy>
<newNode>
<xsl:attribute name="id">newAttr</xsl:attribute>
</newNode>
</xsl:copy>
</xsl:template>
<!-- change existing 'atr111' attribute value to 'atr222' -->
<xsl:template match="a/@type[. = 'atr111']">
<xsl:attribute name="type">atr222</xsl:attribute>
</xsl:template>
我目前的输出结果如下,
<doc>
<a id="id-1"/><a><newNode id="newAttr"/></a>
<a id="id-2"/><a><newNode id="newAttr"/></a>
<a id="id-3"/><a><newNode id="newAttr"/></a>
<a id="id-4"/><a><newNode id="newAttr"/></a>
<a id="id-5"/><a><newNode id="newAttr"/></a>
<a id="id-6"/><a><newNode id="newAttr"/></a>
</doc>
如您所见,动态 ID 已按预期添加,并且具有新属性的 <newNode>
也有 added.but 它复制了 <a>
节点。现有属性 type
也已消失。
如何组织我的代码以获得预期的输出?
您忘记复制 type
属性。 <xsl:copy>
只复制当前节点本身,而不是它的 children 或属性。
下面利用身份模板进行复制children和属性的过程。
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output encoding="UTF-8" indent="yes" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="a[@type='atr111' or @type='atr222']">
<xsl:copy>
<xsl:attribute name="id">
<xsl:text>id-</xsl:text>
<xsl:number count="a[@type='atr111' or @type='atr222']" level="any" />
</xsl:attribute>
<xsl:apply-templates select="@*|node()" />
<newNode id="newAttr" />
</xsl:copy>
</xsl:template>
</xsl:transform>
输出:
<doc>
<a id="id-1" type="atr111"><newNode id="newAttr"/></a>
<a id="id-2" type="atr111"><newNode id="newAttr"/></a>
<a id="id-3" type="atr111"><newNode id="newAttr"/></a>
<a id="id-4" type="atr222"><newNode id="newAttr"/></a>
<a id="id-5" type="atr222"><newNode id="newAttr"/></a>
<a id="id-6" type="atr222"><newNode id="newAttr"/></a>
</doc>
如果没有其他 children,您当然也可以使用 <xsl:copy-of select="@type" />
,但这不太灵活:通过身份模板复制使您能够继承变量输入并添加,例如, 一个 <xsl:template match="a/@type">
later-on 对 @type
节点做一些特殊处理,如有必要。