我正在尝试将xml转换为我的Java类
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "Request")
public class Request {
@XmlElement(name="UserName")
private String username;
@XmlElement(name="Password")
private String password;
@XmlElement(name="XMLPost")
private String xmlPost;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getXmlPost() {
return xmlPost;
}
public void setXmlPost(String xmlPost) {
this.xmlPost = xmlPost;
}}
这是我的背景
JAXBContext jc = JAXVContext.newInstance(Request.class, Report.class, Status.class);
StringReader reader = new StringReader(xml);
Unmarshaller unmarshaller = jc.createUnmarshaller();
以下是我如何一起使用它们
Request request = unmarshaller.unmarshal(reader);
在Request
类中,xmlPost
将包含Report
的xml或Status
的xml所以我想将其捕获为字符串,以便我可以尝试解组每个案件。
Report
课程来自我无法控制的第三方请求。但是当我尝试解散Request
时,如果XMLPost
字段中有任何XML,它也会尝试解组它,即使我已经指定它应该只是String
。为什么我不能将XMLPost
中的xml填充到String
?
感谢先进的所有帮助。
答案 0 :(得分:1)
你可以使用cusom处理程序来转换它,请查看这篇文章。我希望它可以帮助您解决问题:http://blog.bdoughan.com/2011/04/xmlanyelement-and-non-dom-properties.html
答案 1 :(得分:1)
您无法直接执行此操作,因为它不遵循XML规范。 定义时:
@XmlElement(name="XMLPost")
private String xmlPost;
这意味着根据XML规范的JAXB要求XML使用简单的类型元素XMLPost作为xs:string。不是另一个XML元素。 要获得值,您的请求必须如下:
<Request>
<XMLPost>some string in it</XMLPost>
</Request>
所以,如果你想在其中使用另一个XML作为String,你必须使用XML转义形式,如:
<Request>
<XMLPost><Report> ...xml escaped content... </Report></XMLPost>
</Request>
或作为CDATA元素。
<Request>
<XMLPost><![CDATA[<Report> ...xml content... </Report>]]></XMLPost>
</Request>
从其他人手中,您可以将两个字段作为复杂的XML元素
@XmlElement(name="Report")
private Report report;
@XmlElement(name="Status")
private Status status;
在这种情况下,您必须拥有Report和Status的JAXB类 然后,如果您的Request有Report元素,那么 报告字段将具有它,状态将为空 或者当Request有状态时,状态字段将显示它,报告字段将为空。
如果你需要你的报告和状态而不需要使用字符串并单独解组,这可能是更合适的方法。这取决于您以及您需要对这些元素做些什么......
就XML Schema而言:
<xs:element name="Request">
<xs:complexType>
<xs:sequence>
<xs:element name="XMLPost" type="xs:string">
</xs:sequence>
</xs:complexType>
</xs:element>
对于第二种方法,它将如下所示:
<xs:element name="Request">
<xs:complexType>
<xs:sequence>
<xs:element name="Report" minOccurs="0">
<xs:complexType>
<xs:sequence>
<!-- ... Report type definition ... -->
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Status" minOccurs="0">
<xs:complexType>
<xs:sequence>
<!-- ... Status type definition ... -->
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
最后,如果只需要一个字段来保存Report或Status对象(不是String),则将其定义为Object
@XmlElement(name="XMLPost")
private Object xmlPost;
它对应于XSD:
<element name="XMLPost" type="xs:anyType" />
当然,在处理您的请求时,您需要检查什么是xmlPost对象
答案 2 :(得分:1)
我真正要做的是创建一个XMLPost
对象,其中包含可选的report
和status
字段。然后在解组之后,您可以看到填充了哪一个。
但是,要回答原始问题,您应该使用XmlAdapter
(In JAXB, how to use @XmlJavaTypeAdapters annotation?)。以下是适配器的示例:
public class XmlPostStringAdapter extends XmlAdapter<XMLPost, String> {
@Override
public String unmarshal(XMLPost xmlPost) throws Exception {
StringWriter sw = new StringWriter();
JAXBContext jaxbContext = JAXBContext.newInstance(XmlPost.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.marshal(xmlPost, sw);
return sw.toString();
}
@Override
public XMLPost marshal(String xmlPost) throws Exception {
JAXBContext jaxbContext = JAXBContext.newInstance(XMLPost.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
return (XMLPost) jaxbUnmarshaller.unmarshal(new StringReader(xmlPost));
}
}