2011-05-11 61 views
3

我希望我的標題能夠正確處理這個問題。請考慮下面的XSL塊和XSL示例塊。用於XSL轉換的XML文本格式

<root> 
<level_one> 
My first line of text on level_one 
<level_two> 
My only line of text on level_two 
</level_two> 
My second line of text on level_one 
</level_one> 
</root> 

<xsl:template match="level_one"> 
<xsl:value-of select="text()"/> 
<br/> 
<xsl:apply-templates select="level_two"/> 
</xsl:template> 

<xsl:template match="level_two"> 
<xsl:value-of select="text()"/> 
<br/> 
</xsl:template> 

既然這樣,執行上述當輸出(這裏修改後用於讀取)是

My first line of text on level_one 
<br/> 
My only line of text on level_two 
<br/> 

我缺少文本的上level_one第二行。所以我想知道兩件事情。

  1. XML是否有效?據我所知,答案是肯定的,但我錯了嗎?
  2. 如何修改XSL以獲得第二行(或者我的例子中的行數超過了我所展示的)?

感謝

+1

我認爲它不是一個好的xml樣式來放置文本之間的子標籤 – martin 2011-05-11 16:53:07

+0

好問題,+1。請參閱我的答案以解釋此問題的原因以及簡單自然的解決方案。 – 2011-05-12 02:33:07

回答

0

是XML有效?據我所知, 答案是肯定的,但我錯了嗎?

是的,你的XML是有效的。另外,與上面的評論相反,將XML中的混合內容(文本和元素混合在一起)沒有任何問題。這一切都取決於上下文以及如何使用XML。例如,如果沒有混合內容,編寫技術手冊幾乎是不可能的。 (一個很好的例子是在段落元素與文字混合參考元素。)

我如何修改XSL以 獲得第二線(甚至更多 線在我的情況比我展示) ?

我不知道你要完成什麼,但你沒有看到文本的第二行的原因是因爲你只匹配與第一<xsl:value-of select="text()"/>第一線。

我不知道這是否會在你的全套XML數據的工作,但你可以同時取代level_onelevel_two模板與一個模板匹配所有text()

<xsl:template match="text()"> 
    <xsl:value-of select="."/> 
    <br/> 
    </xsl:template> 

這將產生以下輸出:

012:

My first line of text on level_one 
    <br/> 
    My only line of text on level_two 
    <br/> 
    My second line of text on level_one 
    <br/> 

你也可以通過指定level_one和level_two父母縮小比賽下來

這會產生完全相同的輸出,但會留下任何其他文本以在其他模板中進行匹配。

希望這會有所幫助。

+0

是的,它幫助了很多!我避免使用一般的text()模板,以便我可以更好地控制結構和輸出。我最終使用了一般的text()模板,但是規定檢查父項,以便它只在需要的地方生效。 – james 2011-05-11 18:22:17

+0

不客氣。 +1爲好問題 – 2011-05-11 19:04:03

1

使用使用xsl:apply-templates的遞歸下降的標準XSLT處理模型。

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

<xsl:template match="text()"> 
<xsl:value-of select="."/> 
<br/> 
</xsl:template> 

使用<xsl:value-of select="text()"/>是個壞消息。在XSLT 1.0中,它只顯示第一個文本節點(就像您發現的那樣)。在XSLT 2.0中,它顯示所有的子文本節點,空格分隔,但這可能不是你想要的,因爲它會在第二個之前輸出第一個和第三個句子。 (其實你還沒說你想要什麼輸出,所以我不得不猜測。)

1

即使不匹配text()模板,你可以通過輸出的當前節點(level_one)的兩個text()節點孩子代替

<xsl:value-of select="text()"/> 

<xsl:copy-of select="text()"/> 

在XSLT 1.0這是非常小鬼ortant知道<xsl:value-of select="$someNodeSet"/>只生成$someNodeSet節點集的第一個節點(按文檔順序)的字符串值。包含在$someNodeSet

<xsl:copy-of select="$someNodeSet"/> 

副本的所有節點:

另一方面

+0

+1在XSLT 1.0中使用value-of-copy-of的最佳解釋。 – 2011-05-12 16:53:08