2017-10-09 71 views
-1

這裏的XML:XSLT:我如何獲得此輸出?

<list title="Shopping list"> 
    <item>Orange juice</item> 
    <item>Bread</item> 
    <item> 
     <list title="Cake ingredients"> 
     <item>Flour</item> 
     <item>Eggs</item> 
     <item>Milk</item> 
     <item>Sugar</item> 
     <item> 
      <list title="Chocolate icing ingredients" 
     </list> 
     <item>Cocoa powder</item> 
     <item>Icing mixture</item> 
     <item>Unsalted butter</item> 
</list> 
</item> 
</list> 
</item> 
</list> 

所需的輸出是:

購物清單:
1麪包
蛋糕原料
2.1巧克力糖衣配料:
2.1.1可可粉末
2.1.2結冰混合物
2.1.3無鹽黃油
個 2.2雞蛋
2.3麪粉
2.4奶
2.5糖業
3橙汁

我怎麼會去這樣做呢?我能夠使用position()來爲一些節點編號並對某些元素進行排序,但是我無法完成所有這些工作。

+2

你說你已經可以使用position()來給節點編號了,所以讓我們看看你迄今爲止做了什麼。 – Steve

+1

你真的想在這裏輸出文本嗎?或者你是否真的試圖輸出HTML? –

+1

@TimC我想輸出文本 – fredjohnson

回答

0

您沒有說明它明確的,但我注意到:

  • 的元素在特定級別包括應包括:
    • 「葉子」 item元素(無後繼節點), 文本打印是他們的內容,
    • list元素 - 「非葉」 item元素, 但此時的孩子文本打印是他們title屬性。
  • 在特定級別所需的排序是要打印的文本。

爲了獲得所需的遞歸,腳本應該 開始應用模板到根list元素,然後將模板 到下一級的元素。

我爲這兩種情況寫了一個「通用」模板(list和葉item 元素)。

該模板有2個可選參數:

  • nr - 元素數目(在這個水平),
  • prefix - 從更高級別的累積數。

pref變量包含要打印 並且還在遞歸模板應用程序使用的「組合」(多級)數。

該模板的最後一部分包括兩個變體,分別爲listitem

list的變體:

  • 打印title屬性,
  • 選擇用於下一級的元件,
  • 並且在排序循環應用該模板他們。

item變體只是打印內容。

所以整個腳本看上去象下面這樣:

<?xml version="1.0" encoding="UTF-8" ?> 
<xsl:transform version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="text"/> 

    <xsl:template match="/"> 
    <xsl:apply-templates select="list"/> 
    </xsl:template> 

    <xsl:template match="list | item[not(*)]"> 
    <xsl:param name="nr" required="no" select="0"/> 
    <xsl:param name="prefix" required="no" select="''"/> 
    <xsl:variable name="pref" select=" 
     if ($nr = 0) then '' 
     else if ($prefix) then concat($prefix, '.', $nr) 
     else $nr"/> 
    <xsl:value-of select=" 
     if ($pref) then concat($pref, ' ') 
     else ''"/> 
    <xsl:if test="name()='list'"> 
     <xsl:value-of select="concat(@title, '&#xA;')"/> 
     <xsl:variable name="items" select="item[not(*)] | item/list"/> 
     <xsl:for-each select="$items"> 
     <xsl:sort select="if (name() = 'list') then @title else ."/> 
     <xsl:apply-templates select="."> 
      <xsl:with-param name="nr" select="position()"/> 
      <xsl:with-param name="prefix" select="$pref"/> 
     </xsl:apply-templates> 
     </xsl:for-each> 
    </xsl:if> 
    <xsl:if test="name()!='list'"> 
     <xsl:value-of select="concat(., '&#xA;')"/> 
    </xsl:if> 
    </xsl:template> 
</xsl:transform> 

之間「你的」產出和「我的」唯一的區別是, 我的劇本打印也爲list元素(實際上 只蛋糕原料的數量)。

我以爲,你剛剛忘記了這個元素前面 的數字。

還請注意2.1。沒有之前看起來不自然。