Search code examples
jaxbfor-xml-path

JaxB Xpath : How to use multiple xpath to a same java bean?


I need to generate xml using jaxb as below :

<item>
    <key1 id="default">value1</key1>
    <key2 id="default">value2</key2>
    <key3 id="default">value3</key3>
</item>

how to do this using @XmlPath in jaxb?

i have used below one. But i have multiple keys around 50. how to acheive this?

   @XmlPath("key1/@id")
    private String attrValue = "default";

Solution

  • @XmlPath is an extension in the EclipseLink MOXy implementation of JAXB (JSR-222). You will need to use the equivalent in MOXy's mapping file to get the desired behaviour.

    oxm.xml

    What you are looking for is the ability to apply multiple writeable mappings for a field/property. This can't currently be done via annotations, but can be done using MOXy's external mapping document.

    <?xml version="1.0"?>
    <xml-bindings
        xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
        package-name="forum12704491">
        <java-types>
            <java-type name="Item">
                <java-attributes>
                    <xml-element java-attribute="attrValue" xml-path="key1/@id"/>
                    <xml-element java-attribute="attrValue" xml-path="key2/@id" write-only="true"/>
                    <xml-element java-attribute="attrValue" xml-path="key3/@id" write-only="true"/>
                </java-attributes>
            </java-type>
        </java-types>
    </xml-bindings>
    

    Item

    package forum12704491;
    
    import javax.xml.bind.annotation.*;
    
    @XmlRootElement
    @XmlAccessorType(XmlAccessType.FIELD)
    public class Item {
    
        private String attrValue;
        private String key1;
        private String key2;
        private String key3;
    
    }
    

    jaxb.properties

    In order to specify MOXy as your JAXB provider you need to add a file called jaxb.properties in the same package as your domain model with the following entry (see: http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html)

    javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
    

    Demo

    The demo code below demonstrates how to bootstrap using MOXy's external mapping document.

    package forum12704491;
    
    import java.io.File;
    import java.util.*;
    import javax.xml.bind.*;
    import org.eclipse.persistence.jaxb.JAXBContextProperties;
    
    public class Demo {
    
        public static void main(String[] args) throws Exception {
            Map<String, Object> properties = new HashMap<String, Object>(1);
            properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, "forum12704491/oxm.xml");
            JAXBContext jc = JAXBContext.newInstance(new Class[] {Item.class}, properties);
    
            File xml = new File("src/forum12704491/input.xml");
            Unmarshaller unmarshaller = jc.createUnmarshaller();
            Item item = (Item) unmarshaller.unmarshal(xml);
    
            Marshaller marshaller = jc.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.marshal(item, System.out);
        }
    
    }
    

    input.xml/Output

    <?xml version="1.0" encoding="UTF-8"?>
    <item>
       <key1 id="default">value1</key1>
       <key2 id="default">value2</key2>
       <key3 id="default">value3</key3>
    </item>