2009-10-26 63 views
6

假設我正在將任意XML格式的多選測驗轉換爲HTML。每個選項都將在結果文檔中以HTML <li>標籤表示。對於每個選項,如果該選擇是正確的答案,我想要將correct的HTML class添加到<li>。此外,如果該選擇是用戶選擇的選項,我想在<li>中添加一類submitted。因此,如果所提交的以及的選擇是正確的,那麼<li>應具有的correct submitted是否有一種使用XSLT添加多個HTML類的優雅方式?

據我所知,空格分隔的屬性值不是XML數據模型的一部分,因此不能直接通過XSLT創建。然而,我覺得有一種更好的方法可以做到這一點,而不是爲每個可能的類組合使用一個條件(這在本例中是可以接受的,但在更復雜的情況下難以使用)。

如何以優雅的方式解決此問題?期望結果的

例子:

<p>Who trained Obi-Wan Kenobi?</p> 
<ul> 
    <li>Mace Windu</li> 
    <li class="correct submitted">Qui-Gon Jinn</li> 
    <li>Ki-Adi-Mundi</li> 
    <li>Yaddle</li> 
</ul> 

回答

9

首先,XML中的屬性值中的空格沒有問題:粗略地說,attribute value normalization在分析文檔時將空格字符轉換爲空格並將相鄰空格摺疊爲單個空格,但肯定允許空格。 編輯:關於這方面的更多信息,請參閱下文。

馬修威爾遜的方法沒有在可能的值之間加入空格,正如你在你的評論中提到的那樣。但是,他的方法基本上是合理的。拼圖的最後一部分是你不喜歡多餘的空間:這些可以通過使用XPath函數來消除。

以下樣式表將所有的位放在一起 - 請注意,它不會對輸入文檔執行任何操作,因此出於測試目的,您可以針對任何XML文檔甚至針對自身運行它,以驗證輸出是否符合你的要求。

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:variable name="foo0" select="false()"/> 
    <xsl:variable name="bar0" select="true()"/> 

    <xsl:variable name="foo1" select="true()"/> 
    <xsl:variable name="bar1" select="false()"/> 

    <xsl:variable name="foo2" select="true()"/> 
    <xsl:variable name="bar2" select="true()"/> 

    <xsl:template match="/"> 

    <xsl:variable name="foobar0"> 
     <xsl:if test="$foo0"> foo</xsl:if> 
     <xsl:if test="$bar0"> bar</xsl:if> 
    </xsl:variable> 

    <xsl:variable name="foobar1"> 
     <xsl:if test="$foo1"> foo</xsl:if> 
     <xsl:if test="$bar1"> bar</xsl:if> 
    </xsl:variable> 

    <xsl:variable name="foobar2"> 
     <xsl:if test="$foo2"> foo</xsl:if> 
     <xsl:if test="$bar2"> bar</xsl:if> 
    </xsl:variable> 

    <li> 
     <xsl:attribute name="class"> 
     <xsl:value-of select="normalize-space($foobar0)"/> 
     </xsl:attribute> 
    </li> 
    <li> 
     <xsl:attribute name="class"> 
     <xsl:value-of select="normalize-space($foobar1)"/> 
     </xsl:attribute> 
    </li> 
    <li> 
     <xsl:attribute name="class"> 
     <xsl:value-of select="normalize-space($foobar2)"/> 
     </xsl:attribute> 
    </li> 

    </xsl:template> 
</xsl:stylesheet> 

編輯:繼的空間屬性的值的範圍內分離的分立元件的問題是:XML規範的一些可能的有效構建體定義爲attribute types,包括IDREFS和NMTOKENS。第一個案例匹配Names生產,第二個案例匹配NMTokens生產;這兩個製作都被定義爲包含由空格分隔的適當類型的多個值。因此,空格分隔的值列表作爲單個屬性的值是XML信息集的固有組件。

+0

實際上,我關於空白分隔的屬性值的觀點是,XML無法將它們識別爲不同的值 - 它都是一個長字符串(除非我忽略了XML的某個部分)。這就是我在開始使用類屬性時總是感覺有點髒的原因。也就是說,我意識到在我們的編碼器中,只需將空間中的類與空間中的類分開,而不是在各處添加一堆''子元素即可。 – Jakob 2009-10-26 21:36:30

+2

@Jakob:我在回覆結尾處添加了一些關於空格分隔的值列表的詳細信息,這些值構成了一個屬性值。 – NickFitz 2009-10-27 10:36:45

5

關閉我的頭頂,你可以建立一個空格分隔的列表的東西,如:

<li> 
    <xsl:attribute name="class"> 
     <xsl:if cond="...">correct</xsl:if> 
     <xsl:if cond="...">submitted</xsl:if> 
    </xsl:attribute> 
</li> 
+0

這不起作用(至少不使用PHP)。除了'if'元素外,沒有任何空白,也不影響輸出(你需要使用'text'元素)。當然,我可以使用這種解決方案,只需在每個可能的類名稱後添加一個空格,但這會導致冗餘空間,並且看起來比應該需要的更加混亂。 – Jakob 2009-10-26 16:33:07

+1

我已經成功地使用了它,所以也許XSLT處理器與XSLT文件本身的空白處理方式有所不同。 – 2009-10-27 10:33:45

+2

不應'cond'是'test'? – Maarten 2013-11-19 20:59:48

1

至於我知道,空格分隔的屬性值不是XML數據模型的一部分,因此不能直接通過XSLT創建。

除非您正在轉換爲XML語言(不是HTML,XHTML是),否則您不應該擔心XSLT 輸出的XML有效性。這可以是任何東西,並且不需要符合XML!

+0

我不是說空白分隔的屬性值是無效的XML,只是沒有(據我所知)專門生成它們的XSLT構造。 – Jakob 2009-10-26 16:27:23

相關問題