我建議在幾次通過這樣做:
第一遍將標記化在每個subject
的literal
元件列出的類別,並創建用於每一個category
節點。在給定的例子中,這將導致:
<category path="">ANTIQUES</category>
<category path="ANTIQUES/">Americana</category>
<category path="">ANTIQUES</category>
<category path="ANTIQUES/">Art</category>
<category path="">COOKING</category>
<category path="COOKING/">Beverages</category>
<category path="COOKING/Beverages/">General</category>
<category path="">COOKING</category>
<category path="COOKING/">Beverages</category>
<category path="COOKING/Beverages/">Bartending</category>
下一步將選擇所有頂部的類別(即,類別與空@path屬性):
<category path="">ANTIQUES</category>
<category path="">ANTIQUES</category>
<category path="">COOKING</category>
<category path="">COOKING</category>
,減少該進一步只包括不同的值:
<category path="">ANTIQUES</category>
<category path="">COOKING</category>
現在我們終於有一個像樣的起點,在這裏我們可以可以將模板應用到每個這樣的類別做:
<xsl:template match="category">
<node name="{.}" id="{generate-id()}">
<xsl:apply-templates select="$child-categories"/>
</node>
</xsl:template>
其中$child-categories
代表其選擇屬性@path當前@path和電流值的串聯匹配的類別的表達式。
我正在使用每個類別的完整路徑,以防止在分類中分類名稱不唯一的情況下出現錯誤的肯定匹配。
作爲證明的概念,我已經寫了下面的樣式表,利用某些EXSLT擴展函數,即:exsl:節點集(),STR:記號化(),並設置:不同():
XSLT 1.0 + EXSLT
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
xmlns:set="http://exslt.org/sets"
xmlns:str="http://exslt.org/strings"
extension-element-prefixes="exsl set str">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<!-- first-pass -->
<xsl:variable name="categories">
<xsl:for-each select="/Subjects/subject">
<xsl:variable name="steps" select="str:tokenize(literal, '/')" />
<xsl:for-each select="$steps" >
<category>
<xsl:attribute name="path">
<xsl:for-each select="preceding-sibling::token" >
<xsl:value-of select="concat(., '/')" />
</xsl:for-each>
</xsl:attribute>
<xsl:value-of select="." />
</category>
</xsl:for-each>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="category-set" select="exsl:node-set($categories)/category" />
<xsl:template match="/">
<!-- output-->
<nodes>
<xsl:apply-templates select="set:distinct($category-set[not(string(@path))])"/>
</nodes>
</xsl:template>
<xsl:template match="category">
<node name="{.}" id="{generate-id()}">
<xsl:apply-templates select="set:distinct($category-set[@path=concat(current()/@path, current(), '/')])"/>
</node>
</xsl:template>
</xsl:stylesheet>
運行支持所有這些擴展函數(的libxslt)在處理器上時,結果是:
<?xml version="1.0" encoding="UTF-8"?>
<nodes>
<node name="ANTIQUES" id="idp4576">
<node name="Americana" id="idp4704"/>
<node name="Art" id="idp327680"/>
</node>
<node name="COOKING" id="idp25520">
<node name="Beverages" id="idp25648">
<node name="General" id="idp400976"/>
<node name="Bartending" id="idp27984"/>
</node>
</node>
</nodes>
請至少顯示其中一種「多種方法」。謝謝! – 2015-02-09 18:43:19
這不會很簡單。請指出是否使用XSLT 1.0或2.0。 - 代碼的其餘部分是否還有其他含義?(也許可以用來使其更容易)? – 2015-02-09 18:45:49
http://stackoverflow.com/help/someone-answers – 2015-02-19 10:17:31