2012-11-18 38 views
3

我有一個XML文件,其中除了有序列表之外,所有內容都結構良好。每個列表項都被標記爲段落<p>,手動添加枚舉:(1)。我想從該源創建一個有效的HTML列表。從XML結構中的純文本創建HTML列表

使用xsl:matching-substring方法和正則表達式我能夠提取每個列表項,但我似乎無法找到一種方法來添加周圍的<ol>標籤。

下面是一個例子:

XML源:

<Content> 
    <P>(1) blah</P> 
    <P>(2) blah</P> 
    <P>(2) blah</P> 
</Content> 

我到目前爲止有:

<xsl:variable name="text" select="/Content/*/text()"/> 
<xsl:analyze-string select="$text" regex="(\(\d+\))([^(]*)"> 
    <xsl:matching-substring>  
     <![CDATA[<li>]]><xsl:value-of select="regex-group(2)"/><![CDATA[</li>]]> 
    </xsl:matching-substring> 
</xsl:analyze-string> 

輸出:

<li>blah</li> 
<li>blah</li> 
<li>blah</li> 

如果你想知道:輸出必須是普通的xt通常,只有$text變量的內容必須以HTML格式輸出。這就是爲什麼我使用<![CDATA[]]

+0

提供的代碼不應該產生任何結果,但會出現以下錯誤:「來自Saxonica Java版本1.6的Saxon 9.1.0.5J。0_31 Stylesheet編譯時間:586毫秒 處理文件:/ C:/Program%20Files/Java/jre6/bin/marrowtr.xml 構建文件的目錄樹:/ C:/ Program%20Files/Java/jre6/bin/marrowtr。使用net.sf.saxon.tinytree.TinyBuilder 樹XML內置在0毫秒 誤差對marrowtr.xsl的第6行: XPTY0004:多個項目的序列不允許作爲 XSL的@select屬性:分析字符串(「(1)blah」,「(2)blah」,...) 轉換失敗:報告運行時錯誤 「 –

+0

@KelvinMackay,Understood。注意OP正在創建* tags *作爲字符串 - 這是完全錯誤的,這些字符串可能不會被解釋爲HTML元素,而只是字符串。XSLT doesn'不處理「標籤」,但有*節點*。因此,正確的轉換會創建元素,而不是正好是這些元素的序列化的字符串。 –

回答

3

像這樣簡單

I. XSLT 2.0溶液:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:template match="/*"> 
    <ol> 
    <xsl:apply-templates/> 
    </ol> 
</xsl:template> 

<xsl:template match="P[matches(., '(^\(\d+\)\s*)(.*)')]"> 
    <li> 
     <xsl:analyze-string select="." regex="(^\(\d+\)\s*)(.*)"> 
      <xsl:matching-substring> 
       <xsl:value-of select="regex-group(2)"/> 
      </xsl:matching-substring> 
     </xsl:analyze-string> 
    </li> 
</xsl:template> 
</xsl:stylesheet> 

當這個變換所提供的XML文檔應用:

<Content> 
    <P>(1) blah</P> 
    <P>(2) blah</P> 
    <P>(2) blah</P> 
</Content> 

wante d,正確的結果產生:

<ol> 
    <li>blah</li> 
    <li>blah</li> 
    <li>blah</li> 
</ol> 

II。 XSLT 1.0溶液

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:template match="/*"> 
    <ol> 
    <xsl:apply-templates/> 
    </ol> 
</xsl:template> 

<xsl:template match= 
    "P[starts-with(.,'(') 
    and 
    floor(substring-before(substring(.,2), ')')) 
    = 
    substring-before(substring(.,2), ')') 
    ]"> 
    <li> 
     <xsl:value-of select="substring-after(., ') ')"/> 
    </li> 
</xsl:template> 
</xsl:stylesheet> 

當該變換是在相同的XML文檔(上文)施加相同的正確的結果產生

<ol> 
    <li>blah</li> 
    <li>blah</li> 
    <li>blah</li> 
</ol> 
+0

+1非常好:)刪除我的回覆贊成這個 – Kelvin

+0

@KelvinMackay,不客氣。 –

+0

謝謝!這當然讓我走上正軌。 – user1834166

0

這不是一個真正的解決方案,但Dimitre的解決方案建議略有改進。

(1)爲XSLT 2.0溶液中的模板匹配條件可被簡化爲...

<xsl:template match="P[matches(., '^\(\d+\)')]"> 

如此說來,對於XSL正則表達式:分析字符串應該保持原樣。 (2)可能,這超出了問題的範圍,但問題讀取像html是預期的輸出,所以應該向OP建議html xsl:output方法。