Remove xsi:type, xmlns:xs, and xmlns:xsi from JAXB Generics

后端 未结 3 1338
一向
一向 2021-01-18 16:39

When using JAXB, I\'d like to remove the excess namespaces/types from my XML elements when using Generics. How can I do this or what am I doing wrong? I\'d like to use Gen

3条回答
  •  暗喜
    暗喜 (楼主)
    2021-01-18 17:17

    Test Generic

    Your JAXB (JSR-222) implementation is going to create mappings per class (i.e. TestGeneric, not type (i.e. TestGeneric). As such it is going to treat the value field as type Object. This will result in the xsi:type attributes as your JAXB implementation is adding enough information to be able to unmarshal the same types.

    @XmlAccessorType(XmlAccessType.NONE)
    static class TestGeneric {
        @XmlAttribute public boolean isRequired;
        @XmlElement public T value;
    
        public TestGeneric() {
        }
    
        public TestGeneric(boolean isRequired) {
            this.isRequired = isRequired;
        }
    }
    

    Demo

    Below is an approach you could use. I have introduced subclasses of TestGeneric to represent the different possible types.

    package forum11192623;
    
    import java.io.PrintWriter;
    import java.io.StringWriter;
    
    import javax.xml.bind.*;
    import javax.xml.bind.annotation.*;
    
    public class Demo {
    
        public static void main(String[] args) {
            try {
                TestRoot root = new TestRoot();
                root.name.value = "bobby";
                root.age.value = 102;
                root.color.value = "blue";
    
                JAXBContext context = JAXBContext.newInstance(root.getClass());
                Marshaller marsh = context.createMarshaller();
                marsh.setProperty(Marshaller.JAXB_ENCODING,"UTF-8");
                marsh.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,Boolean.TRUE);
    
                StringWriter sw = new StringWriter();
                PrintWriter pw = new PrintWriter(sw);
                marsh.marshal(root,pw);
                System.out.println(sw.toString());
            }
            catch(Throwable t) {
                t.printStackTrace();
            }
        }
    
        @XmlRootElement
        static class TestRoot {
            @XmlElement public TestString name = new TestString(true);
            @XmlElement public TestInteger age = new TestInteger(true);
            @XmlElement public TestString color = new TestString(true);
        }
    
        @XmlAccessorType(XmlAccessType.NONE)
        @XmlTransient
        @XmlSeeAlso({TestInteger.class, TestString.class})
        static class TestGeneric {
            @XmlAttribute 
            public boolean isRequired;
            public T value;
    
            public TestGeneric() {
            }
    
            public TestGeneric(boolean isRequired) {
                this.isRequired = isRequired;
            }
        }
    
        static class TestInteger extends TestGeneric {
            public TestInteger() {
            }
            public TestInteger(boolean b) {
                super(b);
            }
            @XmlElement
            public Integer getValue() {
                return value;
            }
            public void setValue(Integer value) {
                this.value = value;
            }
        }
    
        static class TestString extends TestGeneric {
            public TestString() {
            }
            public TestString(boolean b) {
                super(b);
            }
            @XmlElement
            public String getValue() {
                return value;
            }
            public void setValue(String value) {
                this.value = value;
            }
        }
    
    }
    

提交回复
热议问题