【问题标题】:XSL err: "Content is not allowed in prolog" - not sure what I got wrong this timeXSL 错误:“prolog 中不允许内容” - 不知道这次我做错了什么
【发布时间】:2017-06-13 16:09:17
【问题描述】:

我有一个程序可以像这样编写一些 XML 文件:

Path path = Paths.get(new URI("file://" + this.destination));
StringBuilder sb = new StringBuilder("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Responses>\n");
// Get a bunch of data from a remote web service
sb.append("</Responses>");
Files.write(path, sb.toString().getBytes(Charset.forName("UTF-8")), StandardOpenOption.CREATE);

读取文件的代码如下所示:

import javax.xml.transform.stream.StreamSource;
// ...
// Load XSLT
Source source = new StreamSource(this.getClass().getClassLoader().getResourceAsStream("my_transform.xsl"));
Transformer transformer = factory.newTransformer(source);
// set parameter
transformer.setParameter("db", dbName);
// Get input file
Source xmlSource = new StreamSource(this.pathToFile.toFile());
// Execute transform
transformer.transform(xmlSource, outputTarget);

变换本身很简单:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" indent="no" encoding="utf-8"
        media-type="text/plain" />
    <xsl:strip-space elements="*" />
    <xsl:param name="db" />
    <xsl:template match="/ELEMENT1/ELEMENT2/ELEMENT3/data[@dbname=$db]">
        <xsl:value-of select="../../@id" />
        <xsl:text>&#x9;</xsl:text>
        <xsl:value-of select="./@primary_id" />
        <xsl:text>&#10;</xsl:text>
    </xsl:template>
</xsl:stylesheet>

XML 文件很大,但看起来还不错,这是其中的前几行:

<?xml version="1.0" encoding="utf-8"?>
<Responses>
<Response id="ID0000123">
  <opt>
    <data  primary_id="ID0000123-01" version="0">

当我的代码尝试执行转换时,它会抛出异常:

错误:“序言中不允许内容。” 错误:“com.sun.org.apache.xml.internal.utils.WrappedRuntimeException:prolog 中不允许内容。” javax.xml.transform.TransformerException:javax.xml.transform.TransformerException:com.sun.org.apache.xml.internal.utils.WrappedRuntimeException:prolog 中不允许内容。 在 com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:749) 在 com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:351) ...

我不确定这是从哪里来的。上次发生在我身上的是字符集不匹配,但在这种情况下,我将文件编写为 UTF-8 并使用 StreamSource 加载它,我认为这会正确加载字符集,所以我不是确定转换失败的原因。

【问题讨论】:

标签: java xml xslt


【解决方案1】:

实际的解决方案与 XML 文件无关。我使用的库有一个错误,因为它返回目录的路径而不是有效的 XML 文件。我试图删除这个问题,但因为它已被回答,我不能。我现在确实觉得很傻......

【讨论】:

    【解决方案2】:

    此错误通常发生在XML头之前有一些字符时:特别检查空白字符(因为它们很难一目了然)开头XML 源文件。

    【讨论】:

    • 一个有趣的想法。我建议还检查文件开头的 UniCode BOMs。
    • @zx485 是的,说得好。十六进制编辑器可能对此有用。如果是这种情况,修复它的一种方法可能是在读取源 XML 时指定正确的 编码Source xmlSource = new StreamSource(new InputStreamReader(new FileInputStream(this.pathToFile.toFile()),"UTF-8"));
    【解决方案3】:

    一个问题可能是Java 8 TransformerFactory的方法

    public abstract Transformer newTransformer(Source source)
        throws TransformerConfigurationException
    

    .transform 只能处理 XSLT-1.0 样式表。
    但是您正在尝试处理 XSLT-2.0 样式表:

    <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> ...
    

    快速浏览一下您的 XSLT 就会发现 XSLT-1.0 足以满足您的需求。

    【讨论】:

    • 你说得对,我不需要 XSLT 2,我认为它包含在模板中。好吧,我已更改为“1.0”,但我得到了同样的错误。
    • @FrustratedWithFormsDesigner:很抱歉读到这个。但这只是随机拍摄;-)
    • 无论如何,这是一个很好的观点。我认为 XSLT 版本不匹配通常会产生不同的错误,尽管我已经有一段时间没有看到它了。
    猜你喜欢
    • 2015-12-15
    • 2019-04-23
    • 1970-01-01
    • 2019-03-09
    • 2014-02-16
    • 1970-01-01
    • 2014-06-19
    • 2019-04-04
    • 2011-10-23
    相关资源
    最近更新 更多