【问题标题】:javax.xml.bind.UnmarshalException: XML document structures must start and end within the same entityjavax.xml.bind.UnmarshalException:XML 文档结构必须在同一实体内开始和结束
【发布时间】:2013-11-13 22:02:42
【问题描述】:

我正在尝试解组从 NCBI 作为 BLAST 输出获得的 XML。不幸的是,它似乎在不应该的地方失败了。我得到的堆栈跟踪是:

org.xml.sax.SAXParseException; systemId: file:/C:/blast_output.xml; lineNumber: 578; columnNumber: 17; XML document structures must start and end within the same entity.
    at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:198)
    at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(ErrorHandlerWrapper.java:177)
    at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:441)
    at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:368)
    at com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(XMLScanner.java:1436)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.endEntity(XMLDocumentFragmentScannerImpl.java:911)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.endEntity(XMLDocumentScannerImpl.java:563)
    at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.endEntity(XMLEntityManager.java:1384)
    at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.load(XMLEntityScanner.java:1774)
    at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.skipSpaces(XMLEntityScanner.java:1502)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.seekCloseOfStartTag(XMLDocumentFragmentScannerImpl.java:1386)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:246)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2778)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:606)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:117)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:510)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:848)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:777)
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213)
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:649)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:203)
    ... 37 more

stacktrace 中引用的 XML 行:

<Hsp_identity>8</Hsp_identity>

以及解组的代码:

JAXBContext jc = JAXBContext.newInstance(BlastOutput.class);
Unmarshaller u = jc.createUnmarshaller();
return (BlastOutput) u.unmarshal(outputFile);

也许有人可以解释这里失败的原因。

【问题讨论】:

  • xml 文档就这样结束了吗?从错误来看,它似乎在抱怨根节点缺少结束标记,但我可能是错的。
  • 这还没有结束。该文件有 602 行长...
  • 嗯,文档是不平衡的,换句话说,您在某处缺少结束标记或者它放错了位置。我对各种 xml 包中的行号有些奇怪,所以这可能不准确。我的建议是将 xml 文件拉入 eclipse 或类似的文件中并对其进行格式化,看看您是否无法确定哪个结束标签丢失/放错了位置。另一种选择是调试 XMLDocumentFragmentScannerImpl 的第 911 行,并查看它所期望的结束标记与找到的内容。
  • 调试时我发现 if (fMarkupDepth != fEntityStack[fEntityDepth]) fMarkupDepth 为 8,fEntityStack 值为 0。手动检查时,xml 中的深度似乎没问题。尝试使用 eclipse 进行格式化,它可以正常工作,所以标记似乎也可以。
  • 在这里抓住稻草,可能是编码不匹配吗?您确定 XML 声明中声明的 encoding="..." 与保存文件的真实编码匹配吗?

标签: java xml jaxb unmarshalling


【解决方案1】:

您的 XML 可能有问题,或者您的配置中 JAXB 正在使用的解析器中存在错误。您可以尝试解组 XMLStreamReader 的实例以强制使用不同的解析器。

import java.io.File;
import javax.xml.bind.*;
import javax.xml.stream.*;
import javax.xml.transform.stream.StreamSource;

public class Demo {

    public static void main(String[] args) throws Exception {
        Demo demo = new Demo();

        XMLInputFactory xif = XMLInputFactory.newFactory();
        File outputFile = new File("input.xml");
        XMLStreamReader xsr = xif.createXMLStreamReader(new StreamSource(outputFile));
        BlastOutput blastOutput = demo.unmarshalBlastOutput(xsr);
    }

    private BlastOutput unmarshalBlastOutput(XMLStreamReader xsr) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(BlastOutput.class);
        Unmarshaller u = jc.createUnmarshaller();
        return (BlastOutput) u.unmarshal(xsr);
    }

}

【讨论】:

  • 这帮助我找到了答案,但它要简单得多。看起来我正在写入文件并使用相同的句柄进行解组。该文件没有完成写入,这就是为什么它找不到匹配的 xml 标签(因为它当时缺少一些标签)。由于文件编写器在解组之前投入了一段时间,我没想到会发生任何奇怪的事情:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-14
  • 1970-01-01
相关资源
最近更新 更多