在使用XSLT在HTML中转换XML之后,HTML标记被“剥离”

时间:2012-10-11 15:50:37

标签: html xml xslt xhtml

我有一个XML文件,其中包含信息的所有节点都在CDATA中。这些信息可能使用一些HTML标记进行格式化,如下所示:

<EventList>
    <Text><![CDATA[<p>Some text <i>is</i> formatted! This is a character entity &#39;</p>]]></Text>
    <ShortText><![CDATA[Some other is only plain]]></ShortText>
    <!-- others more -->
</EventList>

我想在(X)HTML页面中使用XSLT对其进行转换:

<?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 
  method="html" 
  doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" 
  media-type="application/xhtml+xml" 
  encoding="utf-8" 
  omit-xml-declaration="yes" 
  indent="no"
/>
  <xsl:template match="Text">
    <h2><xsl:copy-of select="text()"/></h2>
  </xsl:template>

  <xsl:template match="ShortText">
    <div><xsl:copy-of select="."/></div>
  </xsl:template>
</xsl:stylesheet>

但是应用这种转变会产生一种奇怪的行为。我在XSLT中放置的HTML标签是从浏览器中正确解析和解释的,但CDATA中的标签被剥离了<>&字符,产生了这个输出:

<h2>pSome text iis/i formatted!  This is a character entity #39;/p</h2>
<div>Some other is only plain</div>

起初它看起来像<xsl:output>定义中的问题,但我仍然坚持这一点。我试图使用速记XPath .和函数text(),但输出它是相同的。 任何建议表示赞赏!

1 个答案:

答案 0 :(得分:2)

您的XML表示Text元素的内容是一个字符串,其中没有标记,恰好包含多个XML分隔符,如左尖括号和&符号。你的样式表说要将这个字符串写成一串字符,没有标记,所以符合标准的HTML处理器会这样做,产生类似

的输出。
<H2 xmlns="http://www.w3.org/1999/xhtml"
  >&lt;p&gt;Some text &lt;i&gt;is&lt;/i&gt; formatted! 
  This is a character entity &amp;#39;&lt;/p&gt;</h2>
<div xmlns="http://www.w3.org/1999/xhtml"
  ><ShortText xmlns="">Some other is only plain</ShortText></div>

我引入了换行符来缩短线条。这不是你作为输出显示的内容,这本身就是暗示性的。

获得更好结果的最简单方法是让您的XML开始讲述数据的真相:如果您希望Text元素包含一些HTML元素(如p和i),那么请执行此操作,然后使用标识转换你的数据部分。

如果这个XML的破坏设计是你坚持的东西,那么你可以通过在xsl:value-of元素上使用disable-output-escaping属性来解决这个问题。 (警告:需要使用disable-output-escaping几乎总是表示设计中存在错误的信号。)此版本的Text模板生成输出,其中输入的字符串数据写为XHTML标记:

<xsl:template match="Text">
  <h2><xsl:value-of select="string(.)" 
                    disable-output-escaping="yes"/></h2>
</xsl:template>