我有一些这种形式的XML文件:
<?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和表格)。
Edit2:修改XSL以反映答案中的建议。格式化很好,但嵌入式标签仍然以文本形式出现,而不是被解释。
答案 0 :(得分: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">
答案 1 :(得分: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!
答案 2 :(得分: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>