使用不带XSD的XMLStreamReader解组复杂嵌套XML文件

时间:2017-12-14 12:01:08

标签: java xml jaxb xmlstreamreader

我正在尝试使用XMLStreamReader解组嵌套的XML文件。我的XML文件如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<tns:Envelope
    xmlns:tns="http://www.w3.org/2003/05/soap-envelope-dial"
    xmlns:lmic="http://www.example.com"
    xmlns:producer="http://example1.com/"
    xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
    xmlns:ns5="http://www.example.com/dial/3/0">
<tns:header>
...
...
</tns:header>
<tns:body>
<producer:Producer id="1234">
   <producer:GenParty>
     <producer:NameInfo>
        <producer:Comm>
           <producer:SuppName>DATA</producer:SuppName>
           <producer:ContractNumber>123456</producer:ContractNumber>
        </producer:Comm>
    </producer:NameInfo>
    <producer:Address>
      <Street>ABC</Street>
      <Country>DEF</Country>
       ...
       ...
    </prodcer:Address>
    <producer:Address>
      <Street>ABC</Street>
      <Country>DEF</Country>
       ...
       ...
    </prodcer:Address>
  </producer:GenParty>
</producer:Producer>
</tns:body>
</tns:emvelope>

我创建了以下类:

@XmlRootElement(name="Producer",namespace="http://example.com/")
@XmlAccessorType(XmlAccessType.FIELD)
Class Producer {
    private GenParty;
    // getter method of class GenParty
    // setter method of class GenParty
}

@XmlRootElement(name="GenParty")
@XmlAccessorType(XmlAccessType.FIELD)
class GenParty {
    private NameInfo;
    private List<Address> address;
    //getter of both fields
    // setter of both fields
}

和后续类已定义。

我正在使用XMLStreamReader前进到标记,然后我正在编写我的unmarshaler代码:

JAXBContext jc = JAXBContext.newInstance(Producer.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();                
Producer producer = unmarshaller.unmarshal(xsr,Producer.class).getValue();

但是,我在Producer对象上设置了null值。有什么我做错了吗?我可以解组简单的XML文件,但这种嵌套级别对我来说是个问题。有人可以建议我可以轻松地做到这一点,或者我应该在我的代码框架中进行任何更改吗?

提前多多感谢!

1 个答案:

答案 0 :(得分:0)

说出你做错了什么有点难。然而,我建议在代码中创建一个producer然后编组并解组,以检查是否所有类都没问题。

如果类正常并且编组/解组工作,则import com.sun.xml.internal.ws.streaming.DOMStreamReader; import org.w3c.dom.Document; import org.xml.sax.SAXException; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.stream.XMLStreamReader; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.StringWriter; import java.util.List; public class JAXBTester { public static void main(String[] args) throws JAXBException, ParserConfigurationException, IOException, SAXException { JAXBContext jc = JAXBContext.newInstance(Producer.class); Marshaller marshaller = jc.createMarshaller(); Producer producer = createProducer(); String producerStr = marshalproducer(marshaller, producer); Unmarshaller unmarshaller = jc.createUnmarshaller(); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); DocumentBuilder builder = factory.newDocumentBuilder(); Document document = builder.parse(new ByteArrayInputStream(producerStr.getBytes("UTF-8"))); XMLStreamReader xmlStreamReader = new DOMStreamReader(document); Producer readProducer = unmarshaller.unmarshal(xmlStreamReader, Producer.class).getValue(); if (readProducer == null) { throw new IllegalStateException(); } } private static String marshalproducer(Marshaller marshaller, Producer producer) throws JAXBException { StringWriter writer = new StringWriter(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); marshaller.marshal(producer, writer); String res = writer.toString(); System.out.println(res); return res; } private static Producer createProducer() { Producer producer = new Producer(); GenParty genParty = new GenParty(); producer.setGenParty(genParty); NameInfo nameInfo = new NameInfo(); nameInfo.setInfo("Foo"); genParty.setNameInfo(nameInfo); return producer; } } @XmlRootElement(name = "Producer", namespace = "http://example.com/") @XmlAccessorType(XmlAccessType.FIELD) class Producer { private GenParty genParty; public GenParty getGenParty() { return genParty; } public void setGenParty(GenParty genParty) { this.genParty = genParty; } } @XmlRootElement(name = "GenParty") @XmlAccessorType(XmlAccessType.FIELD) class GenParty { private NameInfo nameInfo; private List<Address> address; public NameInfo getNameInfo() { return nameInfo; } public void setNameInfo(NameInfo nameInfo) { this.nameInfo = nameInfo; } public List<Address> getAddress() { return address; } public void setAddress(List<Address> address) { this.address = address; } } class NameInfo { private String info; public String getInfo() { return info; } public void setInfo(String info) { this.info = info; } } class Address { private String street; public String getStreet() { return street; } public void setStreet(String street) { this.street = street; } } 变量永远不应为空。

以下是此练习的示例:

android {
...
// Configure only for each module that uses Java 8
// language features (either in its source code or
// through dependencies).
compileOptions {
  sourceCompatibility JavaVersion.VERSION_1_8
  targetCompatibility JavaVersion.VERSION_1_8
 }
}

如果使用Java 8执行此代码,则不会抛出任何异常。