Read XML body element having multiple values based on different requests

China☆狼群 提交于 2019-12-11 04:26:48

问题


I am parsing a XML request using Java. The XML structure is like this:

<?xml version="1.0" encoding="UTF-8"?>
<TestServices>
    <header>
        //Header Details
    </header>
    <body>
        <ele1>
            <ele2>
                <ele3>534159XXXXXX0176</ele3>  //Or ele_3, ele03, ele_03             
            </ele2>
        </ele1>
    </body>
</TestServices>

I have created classes for the same to read the Header and Body elements. Each node is a class and I am reading the ele3 value like this.

String ele3 = testServicesRequest.getBody().getEle1().getEle2().getEle3();

The element name for ele3 can be different based on different request. I have used Generate Java class from xsd feature in eclipse and it has generated classes like this.

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "ele3"
})
public class ReqEle2 {
    @XmlElement(name = "ele3", required = true)
    protected String ele3;
    public String getEle3() {
        return ele3;
    }    
    public void setEle3(String value) {
        this.ele3 = value;
    }    
}

My requirement is simple. I just want to put multiple element names for single getEle3() method. eg. ele_3, ele03, ele_03 using less code changes. Or Please suggest me any other efficient way to do that.

For now I am trying to do this like this which I think is not good.

public class ReqEle3 {

    @XmlElement(name = "ele03", required = true)
    protected String ele3_1="";

    @XmlElement(name = "ele_3", required = true)
    protected String ele3_2="";

    @XmlElement(name = "ele3", required = true)
    protected String ele3_3="";

    @XmlElement(name = "ele3_old", required = true)
    protected String ele3_4="";

    public String getEle3() {
        if(ele3_1 != null && !ele3_1.isEmpty()){            
            return ele3_1;  
        }        
        else if(ele3_2 != null && !ele3_2.isEmpty()){           
            return ele3_2;  
        }
        else if(ele3_3 != null && !ele3_3.isEmpty()){           
            return ele3_3;  
        }
        else if(ele3_4 != null && !ele3_4.isEmpty()){           
            return ele3_4;  
        }
        return "";
    }    
}

回答1:


You can write custom deserialiser for ele3 node. To be precise, custom deserialiser for ele2 node because this is the last constant node. Below example contains only required part to understand the solution:

import org.w3c.dom.Element;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.io.StringReader;

public class JaxbApp {

    public static void main(String[] args) throws Exception {
        JAXBContext jaxbContext = JAXBContext.newInstance(ReqEle1.class);
        String xml0 = "<ele1><ele2><ele3>534159XXXXXX0176</ele3></ele2></ele1>";
        String xml1 = "<ele1><ele2><ele_3>534159XXXXXX0176</ele_3></ele2></ele1>";
        String xml2 = "<ele1><ele2><ele03>534159XXXXXX0176</ele03></ele2></ele1>";

        for (String xml : new String[]{xml0, xml1, xml2}) {
            StringReader reader = new StringReader(xml);
            Object unmarshal = jaxbContext.createUnmarshaller().unmarshal(reader);
            System.out.println(unmarshal);
        }
    }
}

@XmlRootElement(name = "ele1")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {"ele2"})
class ReqEle1 {

    @XmlJavaTypeAdapter(ReqEle2XmlAdapter.class)
    @XmlElement(name = "ele2", required = true)
    protected ReqEle2 ele2;

    // getters, setters
}

class ReqEle2XmlAdapter extends XmlAdapter<Object, ReqEle2> {

    @Override
    public ReqEle2 unmarshal(Object v) {
        Element element = (Element) v;
        ReqEle2 reqEle2 = new ReqEle2();
        reqEle2.setEle3(element.getFirstChild().getTextContent());

        return reqEle2;
    }

    @Override
    public Object marshal(ReqEle2 v) throws Exception {
        return null; // Implement if needed
    }
}

class ReqEle2 {

    protected String ele3;

    // getters, setters
}

Above code prints:

ReqEle1{ele2=ReqEle2{ele3='534159XXXXXX0176'}}
ReqEle1{ele2=ReqEle2{ele3='534159XXXXXX0176'}}
ReqEle1{ele2=ReqEle2{ele3='534159XXXXXX0176'}}

See also:

  • JAXB @XmlAdapter for arbitrary XML


来源:https://stackoverflow.com/questions/55204289/read-xml-body-element-having-multiple-values-based-on-different-requests

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!