Search code examples
javaattributesannotationsjaxbjava-6

JAXB : How to add attributes to an inner element


I have the below XML that I want to read. Using JAXB on java 1.6, how do I annotate for the attribute regex ? Can I have the field to be of type boolean ?

<?xml version="1.0" encoding="utf-8"?>

 <authStore>
  <authList>
       <auth>
         <resource>res1</resource>
         <privilege regex = "true">PRIV_FILE_.+?_READ</privilege>   
       </auth>
       <auth>
         <resource>res2</resource>
         <privilege>PRIV_FILE_READ</privilege>   
       </auth>
</authStore>

UPDATE : Is it possible to make the attribute optional ? If yes, when I unmarshal, will I get regex field to be false when a privilege element does not have the optional attribute regex ?

UDPATE2 : I don't want to define separate classes for resource and privilege. Also, I don't want to use MOXy. Pls. suggest solution for sun/oracle JDK 1.6 JAXB only.

UPDATE3 : My current object model is something like this

// AuthStore.java
@XmlRootElement
public class AuthStore {

    @XmlElementWrapper(name = "authList")
    @XmlElement(name = "auth")
    private ArrayList<Auth> authList;

    public void setAuthList(ArrayList<Auth> authList) {
        this.authList = authList;
    }

    public ArrayList<Auth> getAuthsList() {
        return authList;
    }
}


// Auth.java    
@XmlRootElement(name = "auth")
@XmlType(propOrder = { "resource", "privilege" })
public class Auth
{
    private String resource;
    private String privilege;

    @XmlElement(name = "resource")
    public String getResource()
    {
        return resource;
    }

    public void setResource(String resource)
    {
        this.resource = resource;
    }

    @XmlElement(name = "privilege")
    public String getPrivilege()
    {
        return privilege;
    }

    public void setPrivilege(String author)
    {
        this.privilege = author;
    }
}

Solution

  • Because privilege contains an attribute (It's actually complex type), you must create a class to hold both the value and the attribute:

    import java.io.InputStream;
    import java.util.List;
    
    import javax.xml.bind.JAXBContext;
    import javax.xml.bind.Unmarshaller;
    import javax.xml.bind.annotation.XmlAttribute;
    import javax.xml.bind.annotation.XmlElement;
    import javax.xml.bind.annotation.XmlElementWrapper;
    import javax.xml.bind.annotation.XmlRootElement;
    import javax.xml.bind.annotation.XmlValue;
    
    @XmlRootElement(name = "authStore")
    @XmlAccessorType(XmlAccesssType.FIELD)
    public class AuthStore {
        public static void main(String []args) throws Exception {
            InputStream inputStream = AuthStore.class.getResourceAsStream("test.xml");
            JAXBContext jaxbContext = JAXBContext.newInstance(AuthStore.class);
            Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
            AuthStore authStore = (AuthStore)unmarshaller.unmarshal(inputStream);
    
            System.out.println(authStore.getAuthList().get(0).getResource());
            System.out.println(authStore.getAuthList().get(0).getPrivilege().getRegex());
            System.out.println(authStore.getAuthList().get(0).getPrivilege().getValue());
        }
    
        @XmlElementWrapper(name = "authList")
        @XmlElement(name = "auth")
        private List<Auth> authList;
    
        public List<Auth> getAuthList() {
            return authList;
        }
    
        @XmlAccessorType(XmlAccesssType.FIELD)
        public static class Auth {
            @XmlElement(name = "resource")
            private String resource;
            @XmlElement(name = "privilege")
            private Privilege privilege;
    
            public String getResource() {
                return resource;
            }
    
            public Privilege getPrivilege() {
                return privilege;
            }
    
            @XmlAccessorType(XmlAccesssType.FIELD)
                public static class Privilege {
                @XmlAttribute(name = "regex")
                private Boolean regex;
                @XmlValue
                private String value;
    
                public Boolean getRegex() {
                    return regex;
                }
    
                public String getValue() {
                    return value;
                }
            }
        }
    }