【问题标题】:XSLT - Add new attributes and nodeXSLT - 添加新属性和节点
【发布时间】:2015-07-17 06:16:14
【问题描述】:

我有一个如下的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>

我的要求是,

  1. 动态增加id属性到具有atr111atr222属性的节点
  2. 在节点内添加新节点,命名为&lt;newNode&gt;,具有属性id="newAttr",属性atr111atr222
  3. &lt;a&gt;节点属性值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 已按预期添加,带有新属性的 &lt;newNode&gt; 也已添加。但它复制了 &lt;a&gt; 节点。现有属性type 也消失了。

如何组织我的代码以获得预期的输出?

【问题讨论】:

    标签: xml xslt xslt-2.0


    【解决方案1】:

    您忘记复制type 属性。 &lt;xsl:copy&gt; 只复制当前节点本身,而不是其子节点或属性。

    以下使用身份模板进行复制子项和属性的过程。

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

    当然,如果没有其他子项,您当然也可以使用 &lt;xsl:copy-of select="@type" /&gt;,但这不太灵活:通过身份模板进行复制使您能够继承变量输入并添加,例如,&lt;xsl:template match="a/@type"&gt; 稍后如有必要,它会对@type 节点进行一些特殊处理。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-27
    相关资源
    最近更新 更多