JAXB List Tag creating inner class

前端 未结 5 1123
无人及你
无人及你 2020-12-16 17:29

So we have an XSD type in the form:


    
        
            

        
相关标签:
5条回答
  • 2020-12-16 17:36

    Another way would be to drop the surrounding <bars> element, the XML does not look so nice anymore, but it would make the java code easier to read. Together with xjc's simple binding (see http://jaxb.java.net/nonav/jaxb20-fcs/docs/vendorCustomizations.html) it will produce quite pretty and usefull java code.

    0 讨论(0)
  • 2020-12-16 17:36

    When you define Bars as a complex type, Bars will be generated as separated class. Like this I find schema also easier to read. Bars will not be List in Foo unless you change maxOccurs to a value higher than 1 - you cannot do this on xs:all but you can use xs:sequence.

    ...
        <xs:complexType name="Foo">
            <xs:all>
                <xs:element name="Bars" type="Bars" />
            </xs:all>
        </xs:complexType>
    
        <xs:complexType name="Bars">
            <xs:sequence>
                <xs:element name="Bar" type="barType" maxOccurs="unbounded" />
            </xs:sequence>
        </xs:complexType>
    ...
    

    After running xjc: Foo.java:

        ...
        @XmlAccessorType(XmlAccessType.FIELD)
        @XmlType(name = "Foo", propOrder = {
    
        })
        public class Foo {
    
            @XmlElement(name = "Bars", required = true)
            protected Bars bars;
    
            public Bars getBars() {
                return bars;
            }
    
            public void setBars(Bars value) {
                this.bars = value;
            }
        }
    

    Bars.java:

        ...
        @XmlAccessorType(XmlAccessType.FIELD)
        @XmlType(name = "Bars", propOrder = {
            "bar"
        })
        public class Bars {
    
            @XmlElement(name = "Bar", required = true)
            protected List<String> bar;
    
            ...
        }
    

    With xs:seqence to get the list of Bars (maxOccurs="unbounded"): XSD:

        ...
        <xs:complexType name="Foo">
            <xs:sequence>
                <xs:element name="Bars" type="Bars" maxOccurs="unbounded" />
            </xs:sequence>
        </xs:complexType>
    
        <xs:complexType name="Bars">
            <xs:sequence>
                <xs:element name="Bar" type="barType" maxOccurs="unbounded" />
            </xs:sequence>
        </xs:complexType>
        ...
    

    Foo.java:

    ...
    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "Foo", propOrder = {
        "bars"
    })
    public class Foo {
    
        @XmlElement(name = "Bars", required = true)
        protected List<Bars> bars;
    
        public List<Bars> getBars() {
            if (bars == null) {
                bars = new ArrayList<Bars>();
            }
            return this.bars;
        }
    }
    
    0 讨论(0)
  • 2020-12-16 17:47

    Bjarne Hansen's plugin for xjc (https://github.com/dmak/jaxb-xew-plugin) would allow you to stay with "Bars" enclosing element, generating convenient @XmlElementWrapper(name="Bars") annotation.

    0 讨论(0)
  • 2020-12-16 17:52

    You could do the following:

    package example;
    
    import java.util.List;
    
    import javax.xml.bind.annotation.XmlElement;
    import javax.xml.bind.annotation.XmlElementWrapper;
    import javax.xml.bind.annotation.XmlRootElement;
    
    @XmlRootElement(name="Foo")
    public class Foo {
    
        private List<Bar> bar;
    
        public List<Bar> getBar() {
            return bar;
        }
    
        @XmlElementWrapper(name="Bars")
        @XmlElement(name="Bar")
        public void setBar(List<Bar> bar) {
            this.bar = bar;
        }
    
    }
    

    and

    package example;
    
    public class Bar {
    
    }
    

    Then you can process your XML using the following code;

    package example;
    
    import java.io.File;
    
    import javax.xml.bind.JAXBContext;
    import javax.xml.bind.Marshaller;
    import javax.xml.bind.Unmarshaller;
    
    public class Demo {
    
        public static void main(String[] args) throws Exception {
            JAXBContext jc = JAXBContext.newInstance(Foo.class);
    
            Unmarshaller unmarshaller = jc.createUnmarshaller();
            Foo foo = (Foo) unmarshaller.unmarshal(new File("src/forum128/input.xml"));
    
            Marshaller marshaller = jc.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.marshal(foo, System.out);
        }
    }
    
    0 讨论(0)
  • 2020-12-16 17:57

    Maybe below sample helps.

    XML Schema

     <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
        <xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    
          <xs:complexType name="test">
            <xs:sequence>
              <xs:element name="dataList" type="xs:string" nillable="true" minOccurs="0" maxOccurs="unbounded"/>
              <xs:element name="str" type="xs:string" minOccurs="0"/>
            </xs:sequence>
          </xs:complexType>
        </xs:schema>
    

    Java class :

    public class Test {
    
        protected List<String> dataList;
        protected String str;
        public List<String> getDataList() {
            if (dataList == null) {
                dataList = new ArrayList<String>();
            }
            return this.dataList;
        }
    
        public String getStr() {
            return str;
        }
    
        public void setStr(String value) {
            this.str = value;
        }
    
    }
    

    EDIT 1:

    You can reverse engineer from java code to xsd. in JAVA_HOME/bin there is schemagen executable.

    Give your java code and it will create the XSD schema for you using your java class.

    see this link

    schemagen myObj1.java myObj2.java
    
    0 讨论(0)
提交回复
热议问题