Partial-unmarshalling with JAXB

你离开我真会死。 提交于 2019-12-13 11:44:15

问题


I want do partial unmarshaling of big XML.

XML has following structure:

<Records>
    <Contract>
        ...
    </Contract>
    <Contract>
        ...
    </Contract>
    ...
    <Contract>
        ...
    </Contract>
    <Contract>
        ...
    </Contract>
</Records>

And result class generated with XJC:

- Records
    |- Contract

If i follow these(sample from jaxb-ri), i get error:

Exception in thread "main" javax.xml.bind.UnmarshalException: unexpected element (uri:"http://somedomain.com", local:"Contract"). Expected elements are <{http://somedomain.com}Records>

If i use:

<jaxb:globalBindings localScoping="toplevel"/>

I get error:

org.xml.sax.SAXParseException: A class/interface with the same name "com.my.package.Text" is already in use. Use a class customization to resolve this conflict.

But i need change many classes. And this is not solution.


回答1:


/**
 * User: r.ibragimov
 * Date: 04.06.13
 */
public class PartialJAXB1 {

    public static void main(String[] args) throws JAXBException, XMLStreamException, FileNotFoundException {

        final QName qName = new QName("http://www.domain.com","Contract");

        InputStream inputStream = new FileInputStream(new File("c:\\test.xml"));

        // create xml event reader for input stream
        XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
        XMLEventReader xmlEventReader = xmlInputFactory.createXMLEventReader(inputStream);

        // initialize jaxb
        JAXBContext context = JAXBContext.newInstance(Records.class);
        Unmarshaller unmarshaller = context.createUnmarshaller();

        XMLEvent e = null;

        // loop though the xml stream
        while( (e = xmlEventReader.peek()) != null ) {

            // check the event is a Document start element
            if(e.isStartElement() && ((StartElement)e).getName().equals(qName)) {

                // unmarshall the document
                Records.Contract contract = unmarshaller.unmarshal(xmlEventReader, Records.Contract.class).getValue();
                System.out.println(contract);
            } else {
                xmlEventReader.next();
            }

        }

    }
}



回答2:


Generating Top Level Classes

I want get just Records class and separate Contract class.

By default a JAXB implementation will generate classes corresponding to anonymous complex types as static inner classes. If you want everything to be a top level class you can as you stated in your question use the following external binding customization:

<jaxb:bindings
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
    version="2.1">
    <jaxb:globalBindings localScoping="toplevel"/>
</jaxb:bindings>

Resolving Name Conflicts

I get error:

org.xml.sax.SAXParseException: A class/interface with the same name "com.my.package.Text

One of the purposes of the static inner classes is to prevent name conflicts. With all top level classes you can use an external binding file to rename the class generated from a complex type. Below is an example where the class corresponding to the complex type itemType would be generated as Item.

<jaxb:bindings
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
    version="2.1">
    <jaxb:globalBindings localScoping="toplevel"/>
    <jaxb:bindings schemaLocation="company.xsd">
        <jaxb:bindings node="//xsd:element[@name='employee']/xsd:complexType/xsd:sequence/xsd:element[@name='address']/xsd:complexType">
            <jaxb:class name="EmployeeAddress"/>
        </jaxb:bindings>
    </jaxb:bindings>
</jaxb:bindings>

Using the Binding File

You specify the binding file in the XJC call using the -b flag

xjc -b binding.xml your-schema.xsd

For More Information

  • http://blog.bdoughan.com/2011/07/jaxb-xjc-and-nested-classes.html


来源:https://stackoverflow.com/questions/16914628/partial-unmarshalling-with-jaxb

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!