为xmldecoder文件创建JAXB绑定

时间:2014-05-22 13:13:08

标签: java xml xml-parsing jaxb jaxb2

我有一个以XML格式生成数据的应用程序。最初它使用xml解码器生成文件,样本xml如下,

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<java version="1.7.0_17" class="java.beans.XMLDecoder">
 <object class="com.test.Bike">
      <void property="color">
        <string>military-green</string>
      </void>
      <void property="engineCapacity">
        <int>150</int>
      </void>
      <void property="vin">
        <int>215468</int>
      </void>
 </object>
</java>

后来的xml编组技术改为JAXB。

现在我需要编写一个应用程序,它使用JAXB绑定读取新的xml和旧的xml文件。但我面临着遗留xml绑定的问题。由于它有<java>代码,因此我无法将XMLRootElement作为object

所以基于JAXBContext的解组如下

  JAXBContext jaxbContext = JAXBContext.newInstance(Bike.class);
                Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();

   StreamSource xml = new StreamSource("bike.xml");
   JAXBElement<Bike> je1 = jaxbUnmarshaller.unmarshal(xml, Bike.class);
   Bike bike = je1.getValue();

   System.out.println(bike);

Bike Domain对象如下,

public class Bike {

    String color;
    int engineCapacity;
    int vin;

    public Bike() {

    }

    public Bike(int vin, int engineCapacity, String color) {
        this.vin = vin;
        this.engineCapacity = engineCapacity;
        this.color = color;
    }

    public String getColor() {
        return color;
    }

    @XmlElement
    public void setColor(String color) {
        this.color = color;
    }

    public int getEngineCapacity() {
        return engineCapacity;
    }

    @XmlElement
    public void setEngineCapacity(int engineCapacity) {
        this.engineCapacity = engineCapacity;
    }

    public int getVin() {
        return vin;
    }

    @XmlAttribute
    public void setVin(int vin) {
        this.vin = vin;
    }

    public String toString() {
        return "Bike [color=" + color + ", engineCapacity=" + engineCapacity
                + ", vin=" + vin + "]";
    }

}

但总是我得到Bike [color=null, engineCapacity=0, vin=0]

的输出

任何人都可以帮助我有效地使用JAXB绑定这些xmls吗?

1 个答案:

答案 0 :(得分:0)

以下是一个示例,如果您不能解组,它将实际读取XML并将其转换为特定于JAXB的XML。

我将int更改为Integers以允许空值,并且能够检查是否是旧版XML。


import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import java.io.IOException;
import java.io.StringReader;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.stream.StreamSource;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

@XmlRootElement
public class Bike {

    String color;
    Integer engineCapacity;
    Integer vin;

    public Bike() {

    }

    public Bike(int vin, int engineCapacity, String color) {
        this.vin = vin;
        this.engineCapacity = engineCapacity;
        this.color = color;
    }

    public String getColor() {
        return color;
    }

    @XmlElement
    public void setColor(String color) {
        this.color = color;
    }

    public int getEngineCapacity() {
        return engineCapacity;
    }

    @XmlElement
    public void setEngineCapacity(int engineCapacity) {
        this.engineCapacity = engineCapacity;
    }

    public Integer getVin() {
        return vin;
    }

    @XmlAttribute
    public void setVin(int vin) {
        this.vin = vin;
    }

    @Override
    public String toString() {
        return "Bike [color=" + color + ", engineCapacity=" + engineCapacity
                + ", vin=" + vin + "]";
    }


    public static void main(String argv[]) throws Exception {
        StreamSource xml = new StreamSource("bike.xml");        
        JAXBContext jaxbContext = JAXBContext.newInstance(Bike.class);
        Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
        JAXBElement je1 = jaxbUnmarshaller.unmarshal(xml, Bike.class);
        Bike bike = je1.getValue();
        if (bike.color == null && bike.vin == null && bike.engineCapacity == null) {
            System.out.println("LEGACY XML");
            Document doc = Bike.readXml(xml);
            doc.getDocumentElement().normalize();
            NodeList nList = doc.getElementsByTagName("void");
            String color = null;
            Integer vin = null;
            Integer engineCapacity = null;
            NodeList k;
            for (int temp = 0; temp  0) {
                            color = k.item(0).getTextContent();
                        }
                    } else {
                        k = eElement.getElementsByTagName("int");
                        if (k.getLength() > 0) {
                            if (prop.equals("vin")) {
                                vin = Integer.valueOf(k.item(0).getTextContent());
                            } else if (prop.equals("engineCapacity")) {
                                engineCapacity = Integer.valueOf(k.item(0).getTextContent());
                            }
                        }
                    }

                }
            }
            if (vin != null && engineCapacity != null && color != null) {
                bike = new Bike(vin, engineCapacity, color);

                Marshaller m = jaxbContext.createMarshaller();
                m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
                System.out.println("THIS WILL BE THE NEW XML CREATED");
                System.out.println("--------------");
                m.marshal(bike, System.out);
                System.out.println("--------------");
                System.out.println(bike);
            }

        } else {
            System.out.println(bike);
        }

    }

    public static Document readXml(StreamSource is) throws SAXException, IOException, ParserConfigurationException {

        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setValidating(false);
        dbf.setIgnoringComments(false);
        dbf.setIgnoringElementContentWhitespace(true);
        dbf.setNamespaceAware(true);
        DocumentBuilder db = dbf.newDocumentBuilder();
        db.setEntityResolver(new NullResolver());
        InputSource is2 = new InputSource();
        is2.setSystemId(is.getSystemId());
        is2.setByteStream(is.getInputStream());
        is2.setCharacterStream(is.getReader());
        return db.parse(is2);
    }
}

class NullResolver implements EntityResolver {
    @Override
    public InputSource resolveEntity(String publicId, String systemId) throws SAXException,IOException {
        return new InputSource(new StringReader(""));
    }
}