2010-07-16 68 views
1

我有這種形式的一些XML文件:說服火狐解析嵌入XML(應用XSL後)HTML

<?xml version="1.0" encoding="utf-8"?> 
<?xml-stylesheet type="text/xsl" href="biomirror.xsl"?> 
<Thread> 
    <Title> Some thread title </Title> 
    <Posts> 
     <Post> 
      <Author> Me </Author> 
      <Body> 
       This is the post body, which <b>may</b> have embedded XHTML, including all sorts of things like:<br /> 
       <div class="quote">Quotes</div> 
       I know it's XHTML, though, the program spitting out XML verifies that. 
      </Body> 
     </Post> 
    </Posts> 
</Thread> 

我需要把它們格式化成可讀的線程,所以我使用一個CSS樣式表和一個XSL樣式表。 CSS的作品,我知道有一個事實,沒有什麼不妥。我的問題似乎與XSL一樣,因爲任何嵌入式XHTML都不會被Firefox解析。在IE瀏覽器中,它完美地工作,並以適當的格式出現,但在Firefox中它完全是純文本格式。我認爲這與它在輸出前被轉義有關,但我無法弄清楚如何防止這種情況。

XSL是:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output 
    omit-xml-declaration="yes" 
    method="xml" 
    media-type="application/xhtml+xml" 
    indent="no" 
    doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" 
/> 
<xsl:template match="Posts"> 
<xsl:for-each select="Post"> 
    <tr xmlns="http://www.w3.org/1999/xhtml" class="Post"> 
     <td> 
     <div> 
      <table width="100%" cellpadding="0" cellspacing="0"> 
      <tr> 
       <td class="Author"> 
       <xsl:value-of select="Author"/> 
       </td> 
       <td class="Date"> 
       Post <xsl:value-of select="PostID"/> 
       <xsl:choose> 
        <xsl:when test="count(LastPost) > 0"> 
        (lastpost) 
        </xsl:when> 
       </xsl:choose> at <xsl:value-of select="Date"/> 
       </td> 
      </tr> 
      </table> 
     </div> 
     <div class="Body"> 
      <xsl:copy-of select="Body" /> 
     </div> 
     <xsl:choose> 
      <xsl:when test="count(Sig) = 1"> 
      <div class="Sig"> 
       <xsl:value-of disable-output-escaping="yes" select="Sig"/> 
      </div> 
      </xsl:when> 
      <xsl:when test="count(Sig) = 0"> 
      <div class="SigFooter"> </div> 
      </xsl:when> 
     </xsl:choose> 
     </td> 
    </tr> 
</xsl:for-each> 
</xsl:template> 

<xsl:template match="Thread"> 
    <html xmlns="http://www.w3.org/1999/xhtml"> 
    <head> 
     <xsl:choose> 
      <xsl:when test="count(Title) = 1"> 
      <title> 
       <xsl:value-of select="Title"/> 
      </title> 
      </xsl:when> 
     </xsl:choose> 
     <link href="resources/main.css" rel="stylesheet" type="text/css" /> 
    </head> 
    <body> 
     <table class="Thread" align="center" width="90%" height="95%" cellpadding="2em"> 
     <tr> 
      <td colspan="3"> 
      <div class="Title"> 
      <xsl:value-of select="Title"/> 
       <br /> 
       <a href="whatis.xml"> 
       <img src="resources/banner.png" /> 
       </a> 
      </div> 
      </td> 
     </tr> 
     <xsl:apply-templates select="Posts"/> 
     <tr height="100%"> 
     <td valign="bottom"> 
     <div class="Footer"> 
      Footer message n stuff 
      </div> 
     </td> 
     </tr> 
     </table> 
    </body> 
    </html> 
</xsl:template> 

這是一個黑客位和任何奇怪的屬性,我在Visual Studio中指責的。這是我第一次使用XSL(對XML比較熟悉),所以我不知道該怎麼做才能解決這個問題。 :)

現在,我讀了這個問題: XSLT: Parsing HTML embedded in XML? 並試圖將它集成到我的XML和XSL(如上所示)。儘管如此,Firefox仍然不起作用。

編輯:另外,我嘗試了xsl:value-of和xsl:copy-of來輸出內容。值的輸出純文本和尊重我的格式(從CSS),複製輸出純文本和廢墟我的格式(退回到正文格式,無視div和表)。

編輯2:修訂XSL以反映答案的建議。格式化很好,但嵌入的標籤仍然以文本出現,而不是被解釋。

回答

1

首先,你不需要這些聲明:

xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl" 

它的安全刪除它們。

其次,你永遠不需要提及child::軸。這在XSLT中是隱含的,只是將其踢出而不替換。

三,移動XHTML命名空間聲明

xmlns="http://www.w3.org/1999/xhtml" 

<xsl:stylesheet>元素和其他地方將其刪除。

最後但並非最不重要:您是否嘗試過XHTML的正確輸出方法和媒體類型?

<xsl:output method="xml" media-type="application/xhtml+xml"> 
+0

哦,還:CSS在標準渲染模式下區分大小寫。請仔細檢查您的班級名稱是否正確。 – Tomalak 2010-07-16 21:22:56

+0

我的班級名稱是正確的,看起來像。我只是嘗試了所有的建議。它解決了複製忽略樣式的問題,但在頁面周圍引入了一個薄白色邊框,但仍未修復XHTML未被解釋爲這樣的問題。 – ssube 2010-07-16 21:42:31

+0

@peachy:這些只是建議。你做客戶端XSLT處理? – Tomalak 2010-07-16 21:55:36

1

第一:我用Firefox 3.5.9運行此。它沒有問題,但這是錯誤的。

當你說:

<xsl:copy-of select="child::Body" /> 

您應對其內容的非命名空間元素。而且因爲你沒有用XHTML命名空間聲明這些內容,所以這些不是XHTML元素。他們應該有一個xmlns=""聲明。但是我的Firefox版本做錯了事:沒有將命名空間元素(例如b)解釋爲XHTML元素(沒有空的命名空間!)。由於您沒有提供CSS樣式表,因此我無法進行CSS測試(如果沒有名稱空間元素獲取樣式)。

編輯:MSXSL正確xmlns=""聲明增加了在Body,但隨後呈現IE無論MS想。 JA!

+0

我剛剛編輯帖子以反映來自其他答案的建議。樣式很好,我認爲所有的樣式表問題都是固定的。無論哪種方式,我可以自己調試CSS沒問題,我只是不熟悉XSL。我刪除了child :: parts。但是,在Firefox 3.6.6中,它不起作用。你是說用XHTML命名空間聲明內容是什麼? – ssube 2010-07-16 22:30:41

+0

@peachykeen:你需要在輸入中的'Body'元素中添加一個默認的名稱空間聲明爲'xmlns =「http://www.w3.org/1999/xhtml」',同時在這個名字空間中定義一個前綴樣式表作爲'xmlns:xhtml =「http://www.w3.org/1999/xhtml」'並使用'xhtml:Body/node()'xpath選擇'Body'元素內容。 – 2010-07-16 22:37:59

+0

剛剛嘗試過,仍然沒有解析FF 3.6.6中的嵌入式XHTML。不過,如果我誤解了你的話,我會繼續努力。 – ssube 2010-07-16 23:18:42

0

您的XML輸入確實是而不是已嵌入XHTML,因爲這需要那些您希望被識別爲XHTML的元素位於XHTML名稱空間http://www.w3.org/1999/xhtml中。因此,您需要更改輸入以將這些元素放入XHTML名稱空間中,然後確實可以簡單地將它們複製到樣式表中的結果樹中,或者需要更改樣式表以將這些元素轉換爲XHTML名稱空間中的元素。以下是,也做了一些其他更改,如設置版本=「1.0」:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns="http://www.w3.org/1999/xhtml"> 
<xsl:output 
    omit-xml-declaration="yes" 
    method="xml" 
    media-type="application/xhtml+xml" 
    indent="no" 
    doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" 
/> 
<xsl:template match="Posts"> 
<xsl:for-each select="Post"> 
    <tr class="Post"> 
     <td> 
     <div> 
      <table width="100%" cellpadding="0" cellspacing="0"> 
      <tr> 
       <td class="Author"> 
       <xsl:value-of select="Author"/> 
       </td> 
       <td class="Date"> 
       Post <xsl:value-of select="PostID"/> 
       <xsl:choose> 
        <xsl:when test="count(LastPost) > 0"> 
        (lastpost) 
        </xsl:when> 
       </xsl:choose> at <xsl:value-of select="Date"/> 
       </td> 
      </tr> 
      </table> 
     </div> 
     <div class="Body"> 
      <xsl:apply-templates mode="to-xhtml" /> 
     </div> 
     <xsl:choose> 
      <xsl:when test="count(Sig) = 1"> 
      <div class="Sig"> 
       <xsl:value-of disable-output-escaping="yes" select="Sig"/> 
      </div> 
      </xsl:when> 
      <xsl:when test="count(Sig) = 0"> 
      <div class="SigFooter"> </div> 
      </xsl:when> 
     </xsl:choose> 
     </td> 
    </tr> 
</xsl:for-each> 
</xsl:template> 

<xsl:template match="Thread"> 
    <html> 
    <head> 
     <xsl:choose> 
      <xsl:when test="count(Title) = 1"> 
      <title> 
       <xsl:value-of select="Title"/> 
      </title> 
      </xsl:when> 
     </xsl:choose> 
     <link href="resources/main.css" rel="stylesheet" type="text/css" /> 
    </head> 
    <body> 
     <table class="Thread" align="center" width="90%" height="95%" cellpadding="2em"> 
     <tr> 
      <td colspan="3"> 
      <div class="Title"> 
      <xsl:value-of select="Title"/> 
       <br /> 
       <a href="whatis.xml"> 
       <img src="resources/banner.png" /> 
       </a> 
      </div> 
      </td> 
     </tr> 
     <xsl:apply-templates select="Posts"/> 
     <tr height="100%"> 
     <td valign="bottom"> 
     <div class="Footer"> 
      Footer message n stuff 
      </div> 
     </td> 
     </tr> 
     </table> 
    </body> 
    </html> 
</xsl:template> 

    <xsl:template match="*" mode="to-xhtml"> 
    <xsl:element name="{local-name()}"> 
     <xsl:apply-templates select="@* | node()" mode="to-xhtml"/> 
    </xsl:element> 
    </xsl:template> 

    <xsl:template match="@* | text() | processing-instruction() | comment()" mode="to-xhtml"> 
    <xsl:copy/> 
    </xsl:template> 

</xsl:stylesheet>