JAXB将1个XML标记映射到2个变量 [英] JAXB mapping 1 XML Tag to 2 variables
问题描述
我正在尝试使用一个类映射我从XML请求获得的响应。
但xml响应有所不同,具体取决于某些设置。例如,在响应中,我得到标签owner,其中填充了所有者对象的ID。如果我在我的请求中添加一个设置,我将返回完整的所有者数据,如firstname和lastname。现在我想根据响应将所有者标记映射到String变量或Class。
i am trying to use one class to map the response i get from an XML request. But the xml response differs, depending own some settings. For example in a response i get the tag "owner" which is filled with the ID of the owner object. If i add a setting in my request i will get back the full owner data, like the firstname and lastname. Now i want to map the owner tag to either a String variable or a Class depending on the response.
示例:
@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>
推荐答案
您可以使用 @XmlAnyElement (lax = true)
来处理这个用例。此批注允许您将任何XML解组为Java对象(DOM Node
)。在第二步中,可以将节点
解组为所需的对象
You can use @XmlAnyElement(lax=true)
to handle this use case. This annotation allows you to unmarshall any XML to a Java object (DOM Node
). In a second step, it is possible to unmarshall the Node
to the required Object
响应
@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
//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);
这篇关于JAXB将1个XML标记映射到2个变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!