如何在spring boot中忽略可选的xsd属性和list标签

时间:2017-10-20 11:41:07

标签: java xml spring-boot xsd

我有一个xsd如下(不能改变xsd):

<xsd:element name="root">
    <xsd:complexType>
        <xsd:sequence>
            <xsd:element ref="element1"/>
            <xsd:element ref="element2" minOccurs="1" maxOccurs="unbounded"/>
            <xsd:element ref="element3"/>
        </xsd:sequence>
        <xsd:attribute name="lang" type="xsd:string" use="optional"/>
    </xsd:complexType>
</xsd:element>

<xsd:element name="element2">       
    <xsd:complexType>
        <xsd:sequence>
            <xsd:element ref="childElement1"/>
            <xsd:element ref="childElement2"/>
        </xsd:sequence>
        <xsd:attribute name="lang" type="xsd:string" use="optional"/>
    </xsd:complexType>
</xsd:element>
<xsd:element name="element1">       
    <xsd:complexType>
        <xsd:simpleContent>
            <xsd:extension base="xsd:string">
                <xsd:attribute name="lang" type="xsd:string" use="optional"/>
            </xsd:extension>
        </xsd:simpleContent>
    </xsd:complexType>
</xsd:element>
<xsd:element name="element3">       
    <xsd:complexType>
        <xsd:simpleContent>
            <xsd:extension base="xsd:string">
                <xsd:attribute name="lang" type="xsd:string" use="optional"/>
            </xsd:extension>
        </xsd:simpleContent>
    </xsd:complexType>
</xsd:element>

...等等.. 从中生成的类如下:

@XmlRootElement(name = "Element1")
public class Element1{

@XmlValue
protected String value;
@XmlAttribute(name = "lang")
protected String lang;
}

,其余的类似。

最终的xml看起来像:

<root>
<Element1>
    <value>1</value>
    <lang/>
</Element1>
<Element2>
    <Element2>
        <ChildElement1>
            <value>2a</value>
                <lang/>
        </ChildElement1>
        <ChildElement2>
                <value>2b</value>
                <lang/>
        </ChildElement2>
    </Element2>
</Element2> 
<Element3>
    <value>3</value>
    <lang>Eng</lang>
</Element3>
<lang/>

但是,我想改为:

  1. 当没有值时,lang标签(可选的xml属性)不应该在xml中。此外,当它们具有值时,它们应该在父标记内。并且值也应该填充在父元素标记内而不是独立的值标记中。
  2. 只有1个元素时,element2的列表,不应该有2个标签。

    这样的事情:

    <root>
    <Element1>1</Element1>  
        <Element2>
            <ChildElement1>2a</ChildElement1>
            <ChildElement2>2b</ChildElement2>
        </Element2>
    <Element3 lang="Eng">3</Element3>
    

    有没有办法实现这个?

  3. 这基本上是休息操作的响应。我正在使用spring boot,所以我没有明确使用JaxB编组和解组。

    编辑:忘记提及我的pom中有jackson-xml-formatter依赖(和woodstox一起)。

    最后,对于包含大量代码段的长篇文章感到抱歉。不知道如何描述我的问题。

1 个答案:

答案 0 :(得分:0)

这是一个自给自足的文件来实现这一目标。基本上有一个包含所有元素的根。我只是快速写下来给你一个想法。您可以根据需要更改方法名称,类名称。

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlValue;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "Element1")
public class Element1 {

    @XmlValue
    protected String value;
    @XmlAttribute(name = "lang")
    protected String lang;

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public String getLang() {
        return lang;
    }

    public void setLang(String lang) {
        this.lang = lang;
    }

    public static void main(String[] args) throws Exception {

        Root r = new Root();
        Element1 e1 = new Element1();
        e1.setValue("1");
        Element2 e2 = new Element2();
        Element1 ce1 = new Element1();
        ce1.setValue("2a");
        e2.setChildElement1(ce1);
        Element1 ce2 = new Element1();
        ce2.setValue("2b");
        e2.setChildElement2(ce2);
        r.setElement2(e2);
        r.setElement(e1);
        Element1 e3 = new Element1();
        e3.setValue("3");
        e3.setLang("eng");
        r.setElement3(e3);
        JAXBContext jc = JAXBContext.newInstance(Root.class);
        Marshaller marrshaller = jc.createMarshaller();
        marrshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

        marrshaller.marshal(r, System.out);
    }
}

@XmlRootElement(name = "root")
@XmlAccessorType(XmlAccessType.FIELD)
class Root {

    @XmlElement(name = "Element1")
    Element1 element;

    @XmlElement(name = "Element2")
    protected Element2 element2;

    public Element2 getElement2() {
        return element2;
    }

    public void setElement2(Element2 element2) {
        this.element2 = element2;
    }

    @XmlElement(name = "Element3")
    Element1 element3;

    public Element1 getElement3() {
        return element3;
    }

    public void setElement3(Element1 element3) {
        this.element3 = element3;
    }

    public Element1 getElement() {
        return element;
    }

    public void setElement(Element1 element) {
        this.element = element;
    }
}

@XmlRootElement(name = "Element2")
@XmlAccessorType(XmlAccessType.FIELD)
class Element2 {

    public Element1 getChildElement1() {
        return childElement1;
    }

    public void setChildElement1(Element1 childElement1) {
        this.childElement1 = childElement1;
    }

    public Element1 getChildElement2() {
        return childElement2;
    }

    public void setChildElement2(Element1 childElement2) {
        this.childElement2 = childElement2;
    }

    @XmlElement(name = "ChildElement1")
    Element1 childElement1;

    @XmlElement(name = "ChildElement2")
    Element1 childElement2;
}