有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java JAXB将1个XML标记映射到2个变量

我试图使用一个类来映射从XML请求得到的响应。 但是xml响应不同,这取决于您自己的一些设置。例如,在一个响应中,我得到了标记“owner”,它填充了owner对象的ID。如果我在请求中添加了一个设置,我将返回完整的所有者数据,比如firstname和lastname。现在,我想根据响应将owner标记映射到字符串变量或类

例如:

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

    @XmlElement
    private String name;

    @XmlElement(name = "owner")
    private String ownerSimple;

    @XmlElement(name = "owner")
    private Owner ownerComplex;

}

@XmlRootElement(name = "ownerc")
public class OwnerC {

    @XmlElement
    int id;

    @XmlElement
    String fname;

    @XmlElement
    String lname;
}

要映射的XML:

<response>
    <name>Foo</name>
    <owner>1234</owner>  <!-- in this case it's only a id -->
</response>

<response>
    <name>Foo</name>
    <owner>  <!-- in this case it's the owner class -->
        <id>1234</id>
        <fname>Jon</fname>
        <lname>Doe</lname>
    </owner>
</response>

共 (1) 个答案

  1. # 1 楼答案

    您可以使用@XmlAnyElement(lax=true)来处理这个用例。此注释允许您将任何XML解组到Java对象(DOMNode)。在第二步中,可以将Node解组到所需的对象

    响应

    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlRootElement(name = "domain")
    public class Response {
    
        @XmlElement
        private String name;
    
        @XmlAnyElement(lax=true)
        private Object owner;
    
        private String ownerSimple;
    
        @XmlTransient
        private Owner ownerComplex; 
    

    所有者

    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlRootElement(name = "owner")
    public class Owner {
    
        @XmlElement
        int id;
    
        @XmlElement
        String fname;
    
        @XmlElement
        String lname;
    

    解组器

    //Unmarshaller. Step 1 - Decodes Response and set a DOM Node at Owner
    //Important. Owner class must not be present in JAXB context, letting next step to decode the object properly. 
    //Owner variable at Response class is annotated with @XmlTransient
    JAXBContext jaxbContext = JAXBContext.newInstance(Response.class);
    Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
    Response response = (Response) jaxbUnmarshaller.unmarshal(reader);
    
    //Unmarshaller. Step 2. Convert Node to the suitable Object
    //Considering both cases, simple-> String complex -> Owner Object.      
    String ownerSimple = ((Node)response.getOwner()).getFirstChild().getNodeValue();
    if (ownerSimple != null){
        response.setOwnerSimple(ownerSimple);
    } else {
        JAXBContext jaxbContextOwner = JAXBContext.newInstance(Owner.class);
        Unmarshaller  jaxbUnmarshallerOwner = jaxbContextOwner.createUnmarshaller();
        Owner ownerComplex = (Owner) jaxbUnmarshallerOwner.unmarshal((Node)response.getOwner());
        response.setOwnerComplex(ownerComplex);
    }
    
     //Marshaller to system.out. Your object is well mapped in both cases
     Marshaller marshaller = jaxbContext.createMarshaller();
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
     marshaller.marshal(rx, System.out);