如何将xslt for-each应用于属性?

时间:2012-03-23 06:39:57

标签: xslt saxon

我的XML文档看起来像这样 -

<doc>

  <system_data>
    <registry_item id="1">
      <hive>HKEY_LOCAL_MACHINE</hive>
    </registry_item>
    <file_item id="2">
      <filepath>C:\Windows\System32\msasn1.dll</filepath>    
    </file_item>
  </system_data>

</doc>

我想转换它,例如“id”属性值按顺序递增,例如:

<doc>

  <system_data>
    <registry_item id="10">
      <hive>HKEY_LOCAL_MACHINE</hive>
    </registry_item>
    <file_item id="11">
      <filepath>C:\Windows\System32\msasn1.dll</filepath>    
    </file_item>
  </system_data>

</doc>

我正在使用“identity”设计,我的xsl看起来像这样 -

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                              xmlns:xslt="http://www.w3.org/1999/XSL/Transform">
<xsl:import href="Identity.xsl"/>
<xslt:param name="newID" />
  <xsl:template match="//system_data/*">
      <xsl:for-each select="@id">
        <xsl:attribute name="id">
            <xsl:value-of select="number($newID)+1"/>      
        </xsl:attribute>
      </xsl:for-each>   
  </xsl:template> 
</xsl:stylesheet>

我将newID值传递为“10”。如何选择每个属性并增加其值?

Indentity.xsl看起来像这样 -

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <!-- Whenever you match any node or any attribute -->
  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

当我申请xsl时,我收到以下错误 -

An attribute node (id) cannot be created after the children of the containing element

1 个答案:

答案 0 :(得分:3)

尝试将match="//system_data/*"的模板更改为:

  <xsl:template match="@id">
    <xsl:attribute name="id">
      <xsl:value-of select="number($newID)+count(preceding::*/@id)"/>
    </xsl:attribute>
  </xsl:template>