我试图使用XSLT来转换文档,方法是用整数id标记一组XML节点,从0开始,并为组中的每个节点增加一个。传递给样式表的XML应该被回显出来,但是增加了这个额外的信息。如何使用XSLT使用唯一的,连续的,增加的整数ID来标记特定的节点?
只是要清楚什么我说的,这里是如何这种转变将使用DOM表示:
states = document.getElementsByTagName("state");
for(i = 0; i < states.length; i++){
states.stateNum = i;
}
这是非常简单的使用DOM,但我有更多的麻烦这样做与XSLT。我设计的当前策略是从身份转换开始,然后创建一个全局变量,选择并存储我想要编号的所有节点。然后我创建一个匹配那种节点的模板。这个想法是,在模板中,我会查找匹配节点在全局变量nodelist中的位置,这会给我一个唯一的数字,然后我可以将它设置为一个属性。
这种方法的问题是,位置功能只能与上下文节点使用,所以像下面这样是非法的:
<template match="state">
<variable name="stateId" select="@id"/>
<variable name="uniqueStateNum" select="$globalVariable[@id = $stateId]/position()"/>
</template>
这同样适用于以下情况:
<template match="state">
<variable name="stateId" select="@id"
<variable name="stateNum" select="position($globalVariable[@id = $stateId])/"/>
</template>
为了使用position()在$ globalVariable中查找元素的位置,必须更改上下文节点。
我找到了一个解决方案,但它是非常不理想的。基本上,在模板中,我使用for-each遍历全局变量。 For-each改变上下文节点,所以这允许我以我描述的方式使用position()。问题是,这将通常将O(n)操作转换为O(n^2)操作,其中n是节点列表的长度,因为无论何时匹配模板,都需要遍历整个列表。我认为必须有一个更优雅的解决方案。
总之,这里是我目前(略简体)XSLT样式表:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:s="http://www.w3.org/2005/07/scxml"
xmlns="http://www.w3.org/2005/07/scxml"
xmlns:c="http://msdl.cs.mcgill.ca/"
version="1.0">
<xsl:output method="xml"/>
<!-- we copy them, so that we can use their positions as identifiers -->
<xsl:variable name="states" select="//s:state" />
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="s:state">
<xsl:variable name="stateId">
<xsl:value-of select="@id"/>
</xsl:variable>
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:for-each select="$states">
<xsl:if test="@id = $stateId">
<xsl:attribute name="stateNum" namespace="http://msdl.cs.mcgill.ca/">
<xsl:value-of select="position()"/>
</xsl:attribute>
</xsl:if>
</xsl:for-each>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我会很感激任何意见,任何人都可以提供。谢谢。
好问题(+1)。看到我的答案是一个非常简单但正确的解决方案。:) – 2010-06-07 23:08:42