JAXB如何将嵌套的xml元素解组成字符串?

时间:2016-12-13 16:19:27

标签: java xml jaxb unmarshalling

我正在尝试将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

感谢先进的所有帮助。

3 个答案:

答案 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>&lt;Report&gt; ...xml escaped content... &lt;/Report&gt;</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对象,其中包含可选的reportstatus字段。然后在解组之后,您可以看到填充了哪一个。

但是,要回答原始问题,您应该使用XmlAdapterIn 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));
  }

}