XSLT 2:将具有递增值的元素添加到列表中

时间:2012-10-29 14:47:49

标签: xml xslt xslt-2.0

我是XSLT的新手,花了好几个小时试图找出一个看似简单的问题的解决方案。

我有一个xml文档,其中包含类似的列表:

  <Header>
    <URLList>
      <URLItem type="type1">
        <URL></URL>
      </URLItem>
      <URLItem type="type2">
        <URL>2</URL>
      </URLItem>
    </URLList>
  </Header>

如果它不存在,我现在需要为每个URLItem添加一个“ID”元素。 ID元素的值必须是递增的值。

xml最终应该如下所示:

  <Header>
    <URLList>
      <URLItem type="type1">
        <ID>1</ID>
        <URL></URL>
      </URLItem>
      <URLItem type="type2">
        <ID>2</ID>
        <URL>2</URL>
      </URLItem>
    </URLList>
  </Header>

我一直在尝试各种各样的事情,但无法让它正常工作。

例如,如果我尝试使用模板来匹配List,我将无法获得正确的递增值。 ID值是[2,4],但不是[1,2],因为它应该......这是xslt:

  <xsl:template match="/Header/URLList/URLItem[not(child::ID)]">
    <xsl:copy>
      <ID> <xsl:value-of select="position()"/></ID>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

我也一直试图像这样使用for-each循环:

  <xsl:template match="/Header/URLList">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
    <xsl:for-each select="/Header/URLList/URLItem">
        <xsl:if test="not(ID)">
          <xsl:element name="ID"><xsl:value-of select="position()" /></xsl:element>
        </xsl:if>
    </xsl:for-each>
  </xsl:template>

这样我似乎得到了正确的增量,但新的ID元素出现在父节点上。我无法找到将它们作为URLItem元素的子元素附加的方法。

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:3)

而不是

  <xsl:template match="/Header/URLList/URLItem[not(child::ID)]">
    <xsl:copy>
      <ID> <xsl:value-of select="position()"/></ID>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

使用

  <xsl:template match="/Header/URLList/URLItem[not(child::ID)]">
    <xsl:copy>
      <xsl:apply-templates select="@*"/>
      <ID><xsl:number/></ID>
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>

答案 1 :(得分:0)

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>
<xsl:template match="/">
<Header>
<xsl:apply-templates select="//URLList"/>
</Header>
</xsl:template>
<xsl:template match="URLList">
<URLList>
<xsl:for-each select="URLItem[not(child::ID)]">
<xsl:copy>
    <xsl:apply-templates select="@*"/>
      <ID> <xsl:value-of select="position()"/></ID>
      <xsl:copy-of select="URL"/>
    </xsl:copy>
  </xsl:for-each>
  </URLList>
  </xsl:template>
  <xsl:template match="@*">
<xsl:copy-of select="."/>
  </xsl:template>
</xsl:stylesheet>