【问题标题】:importing xml document into entity structure created by jaxb将 xml 文档导入到 jaxb 创建的实体结构中
【发布时间】:2014-09-09 18:18:00
【问题描述】:

我正在尝试使用 jaxb 将 xml 文档导入到由 jaxb 创建的实体结构中。我下载了 jaxb 2.2.7 并使用了该下载中包含的 create-marshal 示例,但我将 po.xsd 的内容更改为以下内容:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:element name="businessDocument" type="BusinessDocument"/>

  <xsd:complexType name="CompoundId">
    <xsd:attribute name="root"  type="xsd:string"/>
    <xsd:attribute name="extension" type="xsd:string"/>
  </xsd:complexType>

  <xsd:complexType name="EntityType1">
    <xsd:sequence>
        <xsd:element name="typeId" type="CompoundId"/>
        <xsd:element name="entityTitle" type="xsd:string"/>
    </xsd:sequence>
  </xsd:complexType>

  <xsd:complexType name="BusinessDocument">
    <xsd:sequence>
        <xsd:element name="typeId" type="CompoundId"/>
        <xsd:element ref="documentTitle" minOccurs="1"/>
        <xsd:element name="entity1" type="EntityType1"/>
    </xsd:sequence>
  </xsd:complexType>
</xsd:schema>

然后我创建了具有以下结构的po.xml,旨在匹配po.xsd

<?xml version="1.0"?>
<businessDocument>
    <typeId root="docroot1" extension="docext1"/>
    <documentTitle>first document</documentTitle>
    <entity1>
        <typeId root="innerroot1" extension="innerext1"/>
        <entityTitle>inner title</entityTitle>
    </entity1>
</businessDocument>  

我将Main.java 更改为以下形式,以便将po.xml 导入到使用create-marshal 示例build.xml 文件从po.xsd 创建的实体结构中:

package mainpackage;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

import primer.po.*;
import java.io.*;

public class Main {

    public static void main( String[] args ) {
        String filename = "C:\\Temp\\jaxb\\apps\\create-marshal\\po.xml";
        InputStream is = getInputStream(filename);
        try { unmarshal(BusinessDocument.class, is);} 
        catch (JAXBException e) {e.printStackTrace();}
    }

    public static InputStream getInputStream(String filename){
        InputStream is = null;
        try {
            is = new FileInputStream(filename);
            is.close(); 
        } 
        catch (FileNotFoundException e) {e.printStackTrace();}
        catch (IOException e) {e.printStackTrace();}
        return is;
    }

    public static <T> T unmarshal( Class<T> docClass, InputStream inputStream )throws JAXBException {
        String packageName = docClass.getPackage().getName();
        JAXBContext jc = JAXBContext.newInstance( packageName );
        Unmarshaller u = jc.createUnmarshaller();
        JAXBElement<T> doc = (JAXBElement<T>)u.unmarshal( inputStream );
        return doc.getValue();
    }
}

build.xml 的编译部分是:

<!--compile Java source files-->
  <target name="compile" description="Compile all Java source files">
    <echo message="Compiling the schema..." />
    <mkdir dir="gen-src" />
    <mkdir dir="gen-src/primer/po" />
    <xjc schema="po.xsd" package="primer.po" destdir="gen-src">
      <produces dir="gen-src/primer/po" includes="**/*.java" />
    </xjc>
    <echo message="Compiling the java source files..." />
    <mkdir dir="classes" />
    <javac destdir="classes" debug="on">
      <src path="src" />
      <src path="gen-src" />
      <classpath refid="classpath" />
    </javac>
  </target>

但我得到以下堆栈跟踪:

javax.xml.bind.UnmarshalException
 - with linked exception:
[java.io.IOException: Read error]
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:203)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:173)
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:137)
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:184)
    at mainpackage.Main.unmarshal(Main.java:39)
    at mainpackage.Main.main(Main.java:17)
Caused by: java.io.IOException: Read error
    at java.io.FileInputStream.read(Native Method)
    at com.sun.org.apache.xerces.internal.impl.XMLEntityManager$RewindableInputStream.read(XMLEntityManager.java:2932)
    at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(XMLEntityManager.java:704)
    at com.sun.org.apache.xerces.internal.impl.XMLVersionDetector.determineDocVersion(XMLVersionDetector.java:186)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:772)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:737)
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:119)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1205)
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:522)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:200)
    ... 5 more

【问题讨论】:

  • 看来你xsd里面的documentTitle有问题。您有ref,但在任何地方都找不到定义。
  • 我使用了您的 xsd(添加了该文档标题)和 xml。使用 eclipse 生成类,它工作正常。希望清除您的类文件并重新生成应该可以解决问题。
  • 太好了,很高兴您解决了这个奇怪的问题。如果你真的觉得它们有帮助,你可以投票!!

标签: java xml jaxb xsd


【解决方案1】:

您的问题在这里:

is = new FileInputStream(filename);
is.close(); 

因此,您尝试使用 FileInputStream 从文件中解组 XML,但您在 unmarshal 之前 关闭 is 而不是之后?

更新

我从未将 XSD 用于 JAXB,只是在域类上使用它的注释,但您的 XSD 仍然是错误的。尝试从 XSD 的开头删除 documentTitle 元素。

【讨论】:

  • 添加了一些关于您的 XSD 的评论。
  • 除了您的建议之外,我还必须更改po.xsd 顶部的前两个xsd:element 声明的顺序,以便&lt;xsd:element name="businessDocument" type="BusinessDocument"/&gt; 领先于&lt;xsd:element name="documentTitle" type="xsd:string"/&gt;
  • 删除 &lt;xsd:element name="documentTitle" type="xsd:string"/&gt; 只是引发了另一个错误,但根据我的评论,我通过重新排序两个 xsd:element 声明来解决。
猜你喜欢
  • 1970-01-01
  • 2012-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-20
相关资源
最近更新 更多