2012-10-29 40 views
1

我是XSLT的新手,并花了数小时试图找出似乎看起来很琐碎的问题的解决方案。XSLT 2:将具有递增值的元素添加到列表中

我有一个XML文档,其中包含一个这样的名单:

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

如果它不存在,我现在需要的“ID”元素添加到每个URLItem。 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> 

我一直在尝试不同的东西,但不能让它正常工作。例如,如果我尝试使用模板来匹配列表,我无法获得正确的递增值。将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-每个这样的循环:

<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元素的子元素的方法。

任何帮助极大的赞赏。

+0

原因你得到2,4,6而不是1,2,3是在xsl:应用模板元素(这你没有向我们显示)选择空白文本节点以及元素。您可以通过仅选择元素(select =“*”)或通过在开始使用xsl:strip-space之前剥离空白文本节点来避免这种情况。 –

回答

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