0

JAXB is unmarshalling the first elements encountered of each type in an XML document fine but leaving the children of any nested elements of the same type null.

Briefly, the problematic structure is as follows:

sequence->media->audio->track->clipitem(->sequence etc etc)

So, a clipitem may also have a nested sequence, and the whole cycle can repeat recursively.

The first sequence encountered always has media set correctly.

However, for a nested sequence the media element is always null (even though it is in XML)

The classes were generated with xjc from an XSD.

Why would unmarshall not like nested elements? Apart from nesting elements it is all working fine. Is there something special to annotate nested elements? The code and annotations are pretty simple.

Any clues would be appreciated. Thanks, John

JAXBContext jc = JAXBContext.newInstance(Xmeml.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
Xmeml xmeml = (Xmeml) unmarshaller.unmarshal(inFile);


@XmlRootElement(name = "sequence")
public class Sequence {

    @XmlElement(required = true)
    protected String name;
    @XmlElement(required = true)
    protected BigInteger duration;
    @XmlElement(required = true)
    protected Rate rate;
    @XmlElement(required = true)
    protected Timecode timecode;
    @XmlElement(required = true)
    protected BigInteger in;
    @XmlElement(required = true)
    protected BigInteger out;
    @XmlElement(required = true)
    protected Media media;



@XmlRootElement(name = "clipitem")
public class Clipitem {

    @XmlElement(required = true)
    protected String name;
    @XmlElement(required = true)
    protected BigInteger duration;
    @XmlElement(required = true)
    protected Rate rate;
    protected boolean enabled;
    @XmlElement(required = true)
    protected BigInteger in;
    @XmlElement(required = true)
    protected BigInteger out;
    @XmlElement(required = true)
    protected BigInteger start;
    @XmlElement(required = true)
    protected BigInteger end;
    @XmlElement(required = true)
    protected String masterclipid;
    protected boolean ismasterclip;
    @XmlElement(required = true)
    protected Labels labels;
    @XmlElement(required = true)
    protected Comments comments;
    @XmlElement(required = true)
    protected Sequence sequence;

The XML is huge but here is a snippet where media inside a sequence is null when it shouldn't be.

    <track>
        <clipitem id="Nested Sequence">
            <name>Nested Sequence</name>
            <duration>815</duration>
            <rate>
                <ntsc>FALSE</ntsc>
                <timebase>25</timebase>
            </rate>
            <in>0</in>
            <out>815</out>
            <start>815</start>
            <end>1630</end>
            <sequence id="Nested Sequence1">
                <name>Nested Sequence</name>
                <duration>815</duration>
                <rate>
                    <ntsc>FALSE</ntsc>
                    <timebase>25</timebase>
                </rate>
                <timecode>
                    <rate>
                        <ntsc>FALSE</ntsc>
                        <timebase>25</timebase>
                    </rate>
                    <string>01:00:00:00</string>
                    <frame>90000</frame>
                    <source>source</source>
                    <displayformat>NDF</displayformat>
                </timecode>
                <in>-1</in>
                <out>-1</out>
                <media>
                    <video>
                        <format>
                            <samplecharacteristics>
                                <width>1920</width>
                                <height>1080</height>
                                <anamorphic>FALSE</anamorphic>
                                <pixelaspectratio>NTSC-601</pixelaspectratio>
                                <fielddominance>lower</fielddominance>
                                <rate>
                                    <ntsc>FALSE</ntsc>
                                    <timebase>25</timebase>
                                </rate>
John Baker
  • 89
  • 12
  • it looks okish, can you add the xml that is not being parsed correctly. – Zielu Feb 25 '15 at 22:59
  • I added a snippet of the XML where media inside sequence is coming out null. The whole XML is massive so thought better not post it all. – John Baker Feb 26 '15 at 11:05
  • Place somewhere your all beans and exmple of xml that does not unmarshall correctly (Not whole just the one failing branch is enough) and add a link to them. So we can test if the unmarshalling really does not work or is it somehting on your side. In principle it should work. Typical culprit will be namespace issues but you should rather get error messages not nulls. – Zielu Feb 26 '15 at 11:55
  • Here is a zip with the beans, an xml and a testcase class http://mrlimbic.com/test/testcase.zip – John Baker Feb 26 '15 at 12:39
  • In case it matters, I also have eclipselink 2.5.2 on the classpath. – John Baker Feb 26 '15 at 13:01

1 Answers1

0

Your dom objects does not match the xml. For example the sequence has uuid element as first while your bean has it as last, the "updatebehavior" is lost completely. Similar problems with other beans. The attached xml document does not validate against your jaxb model at all, which is probably the reason why it is not read correctly.

To get the schema from your model:

JAXBContext con = JAXBContext.newInstance(Xmeml.class);
File dir = new File("D:\\Temp\\schema");
con.generateSchema(new MySchemaOutputResolver(dir));

class MySchemaOutputResolver extends SchemaOutputResolver {

    protected File baseDir;

    public MySchemaOutputResolver(File dir)
    {
        super();
        baseDir =  dir;
    }

    @Override
    public Result createOutput( String namespaceUri, String suggestedFileName ) throws IOException {
        return new StreamResult(new File(baseDir,suggestedFileName));
    }
}

to validate against the schema when unmarshalling:

JAXBContext con = JAXBContext.newInstance(Xmeml.class);
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = sf.newSchema(new File("D:\\Temp\\schema\\schema1.xsd"));
Unmarshaller umar = con.createUnmarshaller();
umar.setSchema(schema);
Xmeml mem = (Xmeml)umar.unmarshal(new File("D:\\Temp\\testcase\\Surround Test.xml"));
Zielu
  • 8,312
  • 4
  • 28
  • 41
  • Wow. It is fussy about ordering? How do I make it not care about ordering of elements? Ordering will be a problem as the XML I need to parse may vary in order and come from different systems. I generated these from an XSD with XJC. The XSD came from translating a DTD. Then I edited the XSD to get rid of parts I don't need and to make prettier classes. So what should I do? – John Baker Feb 26 '15 at 14:54
  • It is not fussy about ordering if defined so in xsd. If it is sequence in the schema the order matters (hence sequence name) if it is bag it doesnt. The @XmlType(name = "", propOrder = {...}) on your beans enforces that order. If you remove it the order will stop matter. The XSD that you are going to use to generate class must matches your all documents formats that you may recieve, so instread of removing elements they should be marked as minOccurency=0 so they are not required. – Zielu Feb 26 '15 at 14:59
  • Nevertheless, if your xmls may vary so much, generate back the schema from the classes and always use it for validation duirng unmarshaling so at least you will get exceptions not null values in your objects. That way you will know what happend and can update your jaxb model if you need., – Zielu Feb 26 '15 at 15:00
  • That makes sense. So I just tried removing all the XmlType annotations but the same problem still occurs. Is it somehow using the fields in the class as ordering without the XmlType annotation? – John Baker Feb 26 '15 at 15:24
  • Generate schema back from classes and check what are the errors. – Zielu Feb 26 '15 at 15:28
  • I have to stop it caring about order somehow. Depending on the use case and way the xml was produced, the order and what it contains is pretty different. I can't fix this error "Invalid content was found starting with element 'sequence'. One of '{project}' is expected." If I did I would break something else as both ways around are valid. It must be using the class field order, not XmlType. So how do I define something as a "bag" not a sequence? – John Baker Feb 26 '15 at 16:22
  • You currently have required=true on your project (assuming we talking about the Xmeml, so when it is missing it will not work. Change it to false (on all elements). On the schema part all instead of sequence allows any order but if you really have lists of values it will not work as it allows only 0 or 1 instance. Finally If your input xml do not adhere to any format (as it seems) you could write simple xstl transforamtion to put them in order before jaxb processing. – Zielu Feb 26 '15 at 17:11
  • I tried removing all 'required=true'. I also tried propOrder={} which the suggestion here claimed turned off ordering. http://stackoverflow.com/questions/4712760/how-to-tell-jaxb-that-order-of-elements-does-not-matter. I don't really want to tranform. That seems like a hack. I think I will have to give up with JAXB due to it's inflexibility and use another annotation based framework. Maybe this? http://simple.sourceforge.net/download/stream/doc/tutorial/tutorial.php#start – John Baker Feb 26 '15 at 17:35