简体   繁体   中英

Reading XML files in Java

I have a big XML file and several POJO clasess needed to read this XML. When i try read test file with one POJO i use this:

    JAXBContext jaxbContext = JAXBContext.newInstance(Test.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
Test ts = (Test)jaxbUnmarshaller.unmarshal(file);
System.out.println(ts.getName());

But when i have 30 POJOs what i gonna do? Create this 4 lines 30 times? Give me advice.

UPDATE

How i understand from this example http://blog.bdoughan.com/2010/08/using-xmlanyelement-to-build-generic.html for using several POGOs i gonna use

JAXBContext.newInstance("message:customer:product:order");

And in this examle autor have 3 clesses but only in two of it he whire @XmlRootElement annotation. Why?

You could create JAXBContext with all 30 POJOs you have. Also you could store their names in jaxb.index index file in your package, and create JAXBContext.newInstance("your.package")

Here is some details about jaxb.index from javadoc

Alternatively than being listed in the context path, programmer annotated JAXB mapped classes can be listed in a jaxb.index resource file, format described below. Note that a java package can contain both schema-derived classes and user annotated JAXB classes. Additionally, the java package may contain JAXB package annotations that must be processed. (see JLS 3rd Edition, Section 7.4.1. "Package Annotations").

Your classes should be annotated with @XmlRootElement or @XmlType annotations.

Also you could find all classes annotated as @XmlRootElement using scannotation framework, and create JAXBContext with all JAXB POJOs you have.

Please if you have questions, comment and I will update an answer. Hope it helps.

Ideally, you would create the JAXBContext only once and cache it for re-use. Now

But when i have 30 POJOs what i gonna do? Create this 4 lines 30 times?

If all of your 30 POJOs are in the same package (for eg com.abc) then create the context as JAXBContext.newInstance("com.abc")

In this examle autor have 3 clesses but only in two of it he whire @XmlRootElement annotation. Why?

Only the POJOs that correspond to the global element declarations in the XSD Schema have the @XmlRootElement annotation. This is because a global element declaration is a potential root element in an instance document.

It would be better if you can post a sample of your XML Schema and XML instance document for us to provide a more specific answer.

The following should help.

ANNOTATIONS

JAXB model classes do not require any annotations. There is not annotation that indicates that a class should automatically be processed when creating a JAXBContext .

CREATING A JAXBContext

There are two main ways of creating a JAXBContext

1 - On Classes

You pass in an array of domain classes. Mappings are then created for these classes. Mappings are also created for referenced (see WHAT CLASSES ARE BROUGHT IN below).

2 - On Context Paths

My article that you cited ( http://blog.bdoughan.com/2010/08/using-xmlanyelement-to-build-generic.html ) uses a context path. A context path consists of colon delimited package names. Each package must contain either a jaxb.index file or ObjectFactory class. The jaxb.index file is a carriage return separated list of class names you wish to create the JAXBContext on. Just as with creating a JAXBContext on an array of classes, reference classes are also processed.

WHAT CLASSES ARE BROUGHT IN

Below are some of the key concepts involved on what secondary classes are processed when creating a JAXBContext .

1 - Referenced Classes

If a JAXBContext is created on the Foo class, then Bar will also be processed since it is referenced by Foo .

@XmlAccessorType(XmlAccessType.FIELD)
public class Foo {

    private List<Bar> bar;

}

2 - Super Classes

If a class is processed then its super class is also processed. You can put the @XmlTransient annotation on a class to prevent it from being processed (see: http://blog.bdoughan.com/2011/06/ignoring-inheritance-with-xmltransient.html ).

public class Foo extends Bar {
}

3 - Subclasses

If a class is processed then its subclasses are not automatically processed. You can put the @XmlSeeAlso annotation on a class to specify its subclasses that you wish to process.

@XmlSeeAlso({Bar.class})
public class Foo {
}

4 - Classes Referenced from JAXB annotations

If a class is processed, then classes specified on JAXB annotations within that class are also processed

public class Foo {
    @XmlElements({
         @XmlElement(name="a", type=A.class),
         @XmlElement(name="b", type=B.class)
    })
    private Object bar;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM