I am trying to map the following XML structure within a larger document, clearly this isn’t the greatest use of XML ever but this is what I have to work with.
Example simplified for clarity:
<details>
<pictures>
<picture1>
http://domain.com/path/picture1.jpg
</picture1>
<picture2>
http://domain.com/path/picture2.jpg
</picture2>
<picture3>
http://domain.com/path/picture3.jpg
</picture3>
<picture4>
http://domain.com/path/picture4.jpg
</picture4>
<picture5>
http://domain.com/path/picture5.jpg
</picture5>
<picture6>
http://domain.com/path/picture6.jpg
</picture6>
<picture7>
http://domain.com/path/picture7.jpg
</picture7>
</pictures>
</details>
There is a DTD for this document which declares that there will be up to 30 different picture elements numbered 1-30 with the names <picutre[n]/>
What I would like to do is, rather than create 30 different classes for each of these elements called Picture1, Picture2, Picture3 … and so on. I would just like to use a single Picture class and use it for all 30 unique element names.
Below is what I have tried so far.
@XmlRootElement
public class Details {
...
@XmlElementWrapper
@XmlElementRefs({
@XmlElementRef( name="picture1", type=Picture.class ),
@XmlElementRef( name="picture2", type=Picture.class ),
@XmlElementRef( name="picture3", type=Picture.class ),
@XmlElementRef( name="picture4", type=Picture.class ),
@XmlElementRef( name="picture5", type=Picture.class ),
@XmlElementRef( name="picture6", type=Picture.class ),
@XmlElementRef( name="picture7", type=Picture.class ),
@XmlElementRef( name="picture8", type=Picture.class ),
@XmlElementRef( name="picture9", type=Picture.class ),
@XmlElementRef( name="picture10", type=Picture.class ),
@XmlElementRef( name="picture11", type=Picture.class ),
@XmlElementRef( name="picture12", type=Picture.class ),
@XmlElementRef( name="picture13", type=Picture.class ),
@XmlElementRef( name="picture14", type=Picture.class ),
@XmlElementRef( name="picture15", type=Picture.class ),
@XmlElementRef( name="picture16", type=Picture.class ),
@XmlElementRef( name="picture17", type=Picture.class ),
@XmlElementRef( name="picture18", type=Picture.class ),
@XmlElementRef( name="picture19", type=Picture.class ),
@XmlElementRef( name="picture20", type=Picture.class ),
@XmlElementRef( name="picture21", type=Picture.class ),
@XmlElementRef( name="picture22", type=Picture.class ),
@XmlElementRef( name="picture23", type=Picture.class ),
@XmlElementRef( name="picture24", type=Picture.class ),
@XmlElementRef( name="picture25", type=Picture.class ),
@XmlElementRef( name="picture26", type=Picture.class ),
@XmlElementRef( name="picture27", type=Picture.class ),
@XmlElementRef( name="picture28", type=Picture.class ),
@XmlElementRef( name="picture29", type=Picture.class ),
@XmlElementRef( name="picture30", type=Picture.class )
})
public List<Picture> getPictures() {
return this.pictures;
}
public void setPictures( List<Pictures> pictures ) {
this.pictures = pictures;
}
...
}
@XmlElementWrapper
public class Picture {
...
}
This causes getPictures to return null always.
Additionally I tried changing the annotation on the Picture class to be @XmlElementWrapper( name="picture1" ) which resulted in me getting a list returned from getPictures() but only ever containing the <picture1/> element and never the rest.
I know I can resort to getting a list of JAXBElement objects instead but I would rather not if I can avoid it. Any ideas how I can map this?
There are a couple ways you could handle this use case:
Option #1
You could do the following by leveraging
@XmlElements:Option #2
You could map your
Detailsclass as follows:And then use a
StreamReaderDelegateto chop off the numeric suffix:Option #3
If you are using EclipseLink MOXy as your JAXB (JSR-222) provider, then you could use the
@XmlVariableNodeextension that we added: