org.xml.sax.SAXParseException:prolog中不允许使用内容

时间:2011-09-27 12:27:57

标签: java sax

是的,我知道这个问题的一般形式一次又一次被问到。但是,我找不到任何帮助我解决问题的方法,所以发布了这个问题,特别是我的问题。

我试图弄清楚为什么我得到一个SAXParseExceptionContent is not allowed in prolog.),因为OpenSAML库试图解析一些XML。我发现最有用的提示指向文件开头的错误BOM,但没有类似的东西。我还编写了一个快速而肮脏的C#.NET例程,将整个文件作为一个字节数组读取,迭代它并告诉我它们是否为> = 0x80(它没有找到)。 XML标记为utf-8。我希望有人可以就可能出现的问题向我提供一些见解。

XML文件的初始部分(作为十六进制转储)是(注意使用0A作为换行符;完全删除换行符没有明显效果):

000000000  3C 3F 78 6D 6C 20 76 65-72 73 69 6F 6E 3D 22 31   |<?xml version="1|
000000010  2E 30 22 20 65 6E 63 6F-64 69 6E 67 3D 22 55 54   |.0" encoding="UT|
000000020  46 2D 38 22 3F 3E 0A 3C-6D 64 3A 45 6E 74 69 74   |F-8"?>.<md:Entit|
000000030  79 44 65 73 63 72 69 70-74 6F 72 20 78 6D 6C 6E   |yDescriptor xmln|
000000040  73 3A 6D 64 3D 22 75 72-6E 3A 6F 61 73 69 73 3A   |s:md="urn:oasis:|
000000050  6E 61 6D 65 73 3A 74 63-3A 53 41 4D 4C 3A 32 2E   |names:tc:SAML:2.|
000000060  30 3A 6D 65 74 61 64 61-74 61 22 20               |0:metadata"     |

根本原因异常的堆栈跟踪是:

org.xml.sax.SAXParseException: Content is not allowed in prolog.
    org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
    org.apache.xerces.util.ErrorHandlerWrapper.fatalError(Unknown Source)
    org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
    org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
    org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
    org.apache.xerces.impl.XMLScanner.reportFatalError(Unknown Source)
    org.apache.xerces.impl.XMLDocumentScannerImpl$PrologDispatcher.dispatch(Unknown Source)
    org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
    org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
    org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
    org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
    org.apache.xerces.parsers.DOMParser.parse(Unknown Source)
    org.apache.xerces.jaxp.DocumentBuilderImpl.parse(Unknown Source)
    org.opensaml.xml.parse.BasicParserPool$DocumentBuilderProxy.parse(BasicParserPool.java:665)
    my.Unmarshaller.unmarshall(Unmarshaller.java:39)
    ... internal calls omitted for brevity ...
    javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:722)

尝试进行解组的代码是(在此处输入完全限定的名称;希望我不会遗漏一些重要的内容):

package my;

public class Unmarshaller {

    protected static org.opensaml.xml.parse.ParserPool parserPool;

    static {
        org.opensaml.xml.parse.BasicParserPool _parserPool;
        _parserPool = new org.opensaml.xml.parse.BasicParserPool();
        _parserPool.setNamespaceAware(true);
        Unmarshaller.parserPool = _parserPool;
    }

    public Unmarshaller() {
        try {
            org.opensaml.DefaultBootstrap.bootstrap();
        } catch (org.opensaml.xml.ConfigurationException e) {
            throw new java.lang.RuntimeException (e);
        }
    }

    public Object unmarshall(String xml)
    throws org.opensaml.xml.io.UnmarshallingException {
        assert xml != null;
        assert !xml.isEmpty();
        assert Unmarshaller.parserPool != null;

        org.w3c.dom.Document doc;

        try {
            doc =
                (parserPool.getBuilder())
                    .parse( // <<<====== line 39 in original source code is here
                        new org.xml.sax.InputSource(
                            new java.io.StringReader(xml)
                        )
                    );
        } catch (org.xml.sax.SAXException e) {
            throw new org.opensaml.xml.io.UnmarshallingException(e);
        } catch (java.io.IOException e) {
            throw new org.opensaml.xml.io.UnmarshallingException(e);
        } catch (org.opensaml.xml.parse.XMLParserException e) {
            throw new org.opensaml.xml.io.UnmarshallingException(e);
        }

        // ... remainder of function omitted for brevity ...
    }
}

2 个答案:

答案 0 :(得分:6)

我看不到文件转储中的XML片段有什么问题。当你说XML文件验证时,我相信你。

但是,您没有提供水密证据证明解析器看到的 有效。例如:

  • 您可能正在尝试将另一个文件解析为已转储的文件。 (已知这些事情会发生......)。

  • 或者,将XML转换为然后解析的String的方式可能有问题。

尝试转储提供解析器源流的String的前几行。

答案 1 :(得分:0)

有些情况下SAMLReponses是Base64编码的,消费者(Controller或Servlets)需要解码以解决“prolog中不允许内容”的问题

以下是代码段:

// code snippet
String responseMessage = httpServletRequest.getParameter("SAMLResponse");
byte[] decoded = Base64.decode(responseMessage);
ByteArrayInputStream is = new ByteArrayInputStream(decoded);

// write your xml parsing logic here.