xml 错误 xsl 样式表

Posted

技术标签:

【中文标题】xml 错误 xsl 样式表【英文标题】:xml error xsl stylesheet 【发布时间】:2012-11-07 12:10:12 【问题描述】:

我有以下错误

第 1 行第 40 列的错误:文档末尾的额外内容

当尝试输出xml文件时:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="producers.xsl"?>
<producers>
  <producer>
    <id>8</id>
    <name>Emåmejeriet</name>
    <street>Grenvägen 1-3</street>
    <postal>577 39</postal>
    <city>Hultsfred</city>
    <weburl>http://www.emamejerie3t.se</weburl>
  </producer>
</producers>

我已经验证了 xml,我没有收到任何错误。 xsl 模板如下所示

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
    <head><title>Producenter</title></head>
    <body>
        <p>
            <xsl:value-of select="producers/producer/id"/>
        </p>
    </body>
</xsl:template>
</xsl:stylesheet>

我错过了什么?

【问题讨论】:

对我有用,文件真的使用 utf-8 编码吗? 您是否尝试过现有的答案?您当前的 xslt 产生的输出格式不正确,因为它有多个根元素。 【参考方案1】:

html 标记丢失。 XML 必须有一个根元素(您有两个 - headbody) 字符串后错误仍然存​​在

<head><title>Producenter</title></head>

当验证器找到第二个根元素(body)时。

只需添加根 html 标签

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>

    <head><title>Producenter</title></head>
    <body>
        <p>
            <xsl:value-of select="producers/producer/id"/>
        </p>
    </body>
</html>
</xsl:template>
</xsl:stylesheet>

【讨论】:

ahipsa, html 可能会被省略,这不是错误的原因。导致报告错误的原因是输出了 XML 声明,这使得某些浏览器期望转换生成(格式良好的)XML 文档。设置&lt;xsl:output method="html"/&gt; 修复了这个问题,浏览器不再产生错误信息。应该很好地理解这一点:我并不是说html 元素不能存在——只是它的存在对于解决问题不是必需的。 我完全同意你的看法。这个问题有两个解决方案,添加根元素或更改输出方法。附言。对不起我的英语不好。我用谷歌翻译:) 我不小心开始了赏金,试试吧:) @ahipsa,不要后悔这次事故——赏金帮助吸引了人们的兴趣,现在我们有了一个正确而精确的解决方案。来自我的 +1,为恢复您的 100 分做出贡献:) 谢谢,这对我来说是正确的体验,我只是在学习)【参考方案2】:

以下是来自 Safari 和 Opera 的错误消息(IE 和 Firefox 处理 XML 文件正常,Chrome 挂断):

Safari

此页面包含以下错误:

第 1 行第 40 列的错误:文档末尾的额外内容 下面是出现第一个错误之前的页面渲染。

此文档是作为 XSL 转换的结果创建的。这 给出的行号和列号来自转换后的结果。

歌剧

此文档的 XSLT 样式表无效。来自的错误消息 XSLT 引擎:错误:无效的 XML 输出:意外的开始标记(根 元素已指定)

来自 Safari 的消息特别好 - 它确认问题不在于执行转换,而在于生成的结果。

来自 Opera 的消息不太好,但两种浏览器都在谈论同一件事:它们将转换的结果视为 XML,而不是 HTML,并报告结果不是格式正确的事实XML 文档(不是单个顶部元素)。

确实,转换会生成此输出

<?xml version="1.0" encoding="utf-8"?><head><title>Producenter</title></head><body><p>8</p></body>

XML 声明使浏览器期待一个 XML 文档,却发现这不是一个格式良好的 XML 文档。

解决方案

根据分析,修复很简单自然——只需添加以下内容:

<xsl:output method="html"/>

紧接在xsl:stylesheet 指令之后。

现在完整的转变变成了

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>
<xsl:template match="/">
    <head><title>Producenter</title></head>
    <body>
        <p>
            <xsl:value-of select="producers/producer/id"/>
        </p>
    </body>
</xsl:template>
</xsl:stylesheet>

生成的输出不再以 XML 声明开头,内容类型明确指定为text/html

<head>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">

   <title>Producenter</title>
</head>
<body>
   <p>8</p>
</body>

Safari 和 Opera 都愉快地显示结果,没有错误消息。

记住:生成 HTML 输出时,请始终在 &lt;xsl:output&gt; 指令中明确指定。

注意:虽然此答案揭示了问题的真正原因并提供了解决方案,但这并不排除编写良好且完整的 HTML 文档的需要。因此,最好将html 指定为文档的顶部元素。另一个好处是,如果生成的输出的顶部元素是 html,XSLT 处理器会自动推断输出必须是“html”并执行 html 序列化,即使没有明确指定输出方法。

根据W3C XSLT 1.0 Specification

方法属性的默认选择如下。如果

结果树的根节点有一个子元素,

结果树的根节点(即文档元素)的第一个子元素的扩展名称具有本地部分 html(在任何 大小写的组合)和一个空命名空间 URI,以及

结果树根节点的第一个子元素之前的任何文本节点都只包含空白字符,

那么默认的输出方式是html;否则,默认输出 方法是xml。

【讨论】:

以上是关于xml 错误 xsl 样式表的主要内容,如果未能解决你的问题,请参考以下文章

使用 XSL 样式表进行 ADO XML 清理

xsl 在带有样式表的 Multiple 的 xml 文档上创建

XSL 转换以输出许多嵌入式 XSL 样式表

预处理 XSL 样式表 - 包括外部文档

我需要一个简单的命令行程序来使用 XSL 样式表转换 XML [关闭]

使用 XSL 样式表 Java Transformer Factory 对 XMLTag 进行排序