我試圖使用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