2010-08-28 85 views
-1

我試圖轉換一個CHM(Microsoft HTML幫助)文件索引的內容,該索引用XSL保存任意HTML列表中的結構信息(請參閱第一個代碼片段 - 實際索引文件的結構有點不同,但重要的部分在那裏)。我已經檢出了幾個CHM文件的索引,但是ulli標籤結構永遠不會相同。只有一件事是靜態的:有PARAM標籤,其持有的章,節的信息,因爲這個我想僅僅依靠某些的深度信息的任何標題和鏈接到他們的HTML任意列表結構的xsl轉換

參數標籤將列表轉換爲XML結構(主要轉換爲DocBook結構 - 請參閱第二個代碼片段)。

<ul> 
    <li> 
    <param attr="value"/> 
    <ul> 
     <li> 
     <param attr="value"/> 
     <ul> 
      <li> 
      <param attr="value"/> 
      </li> 
     </ul> 
     </li> 
     <li> 
     <param attr="value"/> 
     <ul> 
      <li> 
      <param attr="value"/> 
      </li> 
      <li> 
      <param attr="value"/> 
      </li> 
     </ul> 
     </li> 
     <li> 
     <param attr="value"/> 
     <ul> 
      <li> 
      <param attr="value"/> 
      </li> 
     </ul> 
     </li> 
    </ul> 
    </li> 
</ul> 

我已經成功地一些指數(類似於之前的代碼片段)轉變爲一個DocBook結構,但問題是,我的XSL樣式表是不通用的不夠。如果任何人有想將類似的HTML列表轉換成DocBook結構,只需使用 param標籤的深度信息,請給我一些指示。

所以例如具有X的深度param標籤會被變換爲一個元件,則params與X + 1會被變換爲等當然等等-的深度始終正確嵌套。

<book> 
    <title>value1</title> 
    <chapter> 
    <title>value2</title> 
    <section> 
     <title>value3</title> 
    </section> 
    </chapter> 
    <chapter> 
    <title>value4</title> 
    <section> 
     <title>value5</title> 
    </section> 
    <section> 
     <title>value6</title> 
    </section> 
    </chapter> 
    <chapter> 
    <title>value7</title> 
    <section> 
     <title>value8</title> 
    </section> 
    </chapter> 
</book> 
+0

您提供的文本是*不是*格式良好的XML文檔,這樣可以防止對「深度」以及所需轉換的任何解釋,因爲不能對非格式進行轉換XML。請改正! – 2010-08-28 20:37:48

+1

你想要的結果文本也是非結構化的! – 2010-08-28 21:38:21

+1

採取Dimitre的建議!你只會得到「猜測模式」的答案。 – 2010-08-28 22:33:39

回答

2

如果你的主要問題是如何產生的根據輸入樹的深度不同的元素,那麼下面的樣式表,演示了做這件事的一種方法:第一,count() ING元素上搞清楚嵌套級別ancestor-or-selfaxis,然後使用xsl:element創建一個具有動態確定名稱的元素。

<xsl:stylesheet version="1.0" 
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:template match="li"> 
    <xsl:variable name="depth" select="count(ancestor-or-self::li)"/> 
    <xsl:variable name="tag"> 
     <xsl:choose> 
     <xsl:when test="$depth = 1">book</xsl:when> 
     <xsl:when test="$depth = 2">chapter</xsl:when> 
     <xsl:otherwise>section</xsl:otherwise> 
     </xsl:choose> 
    </xsl:variable> 
    <xsl:element name="{$tag}"> 
     <xsl:apply-templates/> 
    </xsl:element> 
    </xsl:template> 

    <xsl:template match="param"> 
    <title> 
     <xsl:value-of select="@attr"/> 
    </title> 
    </xsl:template> 

</xsl:stylesheet> 

編輯。這是另一種方法。這使用不同的模板來匹配不同深度的源元素。這可能會更容易閱讀,因爲它消除了創建動態命名元素的需要。

<xsl:stylesheet version="1.0" 
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:template match="li[count(ancestor-or-self::li) = 1]"> 
    <book> 
     <xsl:apply-templates/> 
    </book> 
    </xsl:template> 

    <xsl:template match="li[count(ancestor-or-self::li) = 2]"> 
    <chapter> 
     <xsl:apply-templates/> 
    </chapter> 
    </xsl:template> 

    <xsl:template match="li[count(ancestor-or-self::li) &gt; 2]"> 
    <section> 
     <xsl:apply-templates/> 
    </section> 
    </xsl:template> 

    <xsl:template match="param"> 
    <title> 
     <xsl:value-of select="@attr"/> 
    </title> 
    </xsl:template> 

</xsl:stylesheet> 
+0

我剛剛試用過你的樣式表,在大多數情況下,它們都像魅力一樣工作。剩下的唯一問題是,還有一些其他chm索引依靠深度信息無法轉換,因爲特定深度也包含章節信息。 儘管如此,非常感謝您的幫助,您的回答非常詳盡!你也爲我指出了一些方便的xsl技巧。:) – 2010-08-29 07:12:27

+0

+1模式匹配解決方案 – 2010-08-30 14:28:23