Search code examples
javajaxbjaxb2

How can I change the xml element name that jaxb outputs for each item in a list


If I have a List of objects

    @XmlRootElement(name = "get_item")
    public class GetItem {
       private List<Image> images;
    }

I can pretty much do anything with the Images class even if I need to make three other classes for imgurl, imgcap, imgpurl

I want to produce xml that looks like:

<?xml version=“1.0”?>
<get_item>
 .......snip.......
<imgpurl1>purl 1</imgpurl1>
<imgurl1>url 1</imgurl1>
<imgcap1>caption 1</imgcap1>
<imgpurl2>purl 2</imgpurl2>
<imgurl2>url 2</imgurl2>
<imgcap2>caption 2</imgcap2>
…
<imgpurlN>purl N</imgpurlN>
<imgurlN>url N</imgurlN>
<imgcapN>caption N</imgcapXN>
</get_item>

There is no way to tell how many img(s) there will be. I'd like to have them all in a List and just have it output the three elements I need for each. Is there a way to do this with Jaxb?

The schema I tried to use with Eclipses Jaxb generator looks like:

<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="get_item">
        <xs:complexType>
            <xs:sequence>
                <xs:element type="xs:string" name="title" />
                <xs:element type="xs:string" name="time" />
                <xs:element type="xs:string" name="date" />
                <xs:sequence>
                    <xs:element type="xs:anyURI" name="imgpurl" minOccurs="0" maxOccurs="unbounded" />
                    <xs:element type="xs:anyURI" name="imgurl" minOccurs="0" maxOccurs="unbounded" />
                    <xs:element type="xs:string" name="imgcap" minOccurs="0" maxOccurs="unbounded" />
                </xs:sequence>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

My main concern is to be able to serialize the xml like the example provided...What's the best way to do that? Is there a way to control how Jaxb marshals an object?


Solution

  • It's impossible.
    But you can use xml attribute for it.
    Output will be

    <imgpurl id="1">purl 1</imgpurl>
    <imgurl id="1">url 1</imgurl>
    <imgcap id="1">caption 1</imgcap>
    <imgpurl  id="2">purl 2</imgpurl>
    <imgurl id="2">url 2</imgurl>
    <imgcap id="2">caption 2</imgcap>
    …
    <imgpurl id="N">purl N</imgpurl>
    <imgurl id="N">url N</imgurl>
    <imgcap id="N">caption N</imgcapX>  
    

    xsd:

     <xs:complexType name="ElementWithAttr">
        <xs:simpleContent>
          <xs:extension base="xs:string">
            <xs:attribute name="id" type="xs:integer">
            </xs:attribute>
          </xs:extension>
        </xs:simpleContent>
      </xs:complexType>
            <xs:complexType name="SomeName">
               <xs:sequence>
                  <xs:element type="xs:string" name="title" />
                  <xs:element type="xs:string" name="time" />
                  <xs:element type="xs:string" name="date" />
                  <xs:sequence>
    
                       <xs:element type="ElementWithAttr" name="imgurl" minOccurs="0" maxOccurs="unbounded" />
                       <xs:element type="ElementWithAttr" name="imgcap" minOccurs="0" maxOccurs="unbounded" />
                  </xs:sequence>
              </xs:sequence>
          </xs:complexType>  
    

    generated classes

        public class ElementWithAttr {
    
            @XmlValue
            protected String value;
            @XmlAttribute(name = "id")
            protected BigInteger id;  
       // ...  
        }  
        public class SomeName {
    
           @XmlElement(required = true)
           protected String title;
           @XmlElement(required = true)
           protected String time;
           @XmlElement(required = true)
           protected String date;
           protected List<ElementWithAttr> imgurl;
           protected List<ElementWithAttr> imgcap;  
       // ...  
       }