【问题标题】:Create JAXB binding for xmldecoder files为 xmldecoder 文件创建 JAXB 绑定
【发布时间】:2014-05-22 13:13:08
【问题描述】:

我有一个以 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 绑定的问题。因为它有&lt;java&gt; 标签,我不能把XMLRootElementobject

所以遵循基于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 绑定这些 xml 吗?

【问题讨论】:

    标签: java xml xml-parsing jaxb jaxb2


    【解决方案1】:

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

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

    导入 javax.xml.parsers.DocumentBuilderFactory; 导入 javax.xml.parsers.DocumentBuilder; 导入 org.w3c.dom.Document; 导入 org.w3c.dom.NodeList; 导入 org.w3c.dom.Node; 导入 org.w3c.dom.Element; 导入 java.io.IOException; 导入 java.io.StringReader; 导入 javax.xml.bind.JAXBContext; 导入 javax.xml.bind.JAXBElement; 导入 javax.xml.bind.Marshaller; 导入 javax.xml.bind.Unmarshaller; 导入 javax.xml.bind.annotation.XmlAttribute; 导入 javax.xml.bind.annotation.XmlElement; 导入 javax.xml.bind.annotation.XmlRootElement; 导入 javax.xml.parsers.ParserConfigurationException; 导入 javax.xml.transform.stream.StreamSource; 导入 org.xml.sax.EntityResolver; 导入 org.xml.sax.InputSource; 导入 org.xml.sax.SAXException; @XmlRootElement 公共类自行车{ 字符串颜色; 整数引擎容量; 整数 vin; 公共自行车(){ } 公共自行车(int vin,int engineCapacity,字符串颜色){ 这个.vin = vin; this.engineCapacity = engineCapacity; this.color = 颜色; } 公共字符串 getColor() { 返回颜色; } @XmlElement 公共无效 setColor(字符串颜色){ this.color = 颜色; } 公共 int getEngineCapacity() { 返回引擎容量; } @XmlElement 公共无效 setEngineCapacity(int engineCapacity){ this.engineCapacity = engineCapacity; } 公共整数 getVin() { 返回 vin; } @XmlAttribute 公共无效setVin(int vin){ 这个.vin = vin; } @覆盖 公共字符串 toString() { 返回“自行车 [color=" + color + ", engineCapacity=" + engineCapacity + ", vin=" + vin + "]"; } 公共静态 void main(String argv[]) 抛出异常 { StreamSource xml = new StreamSource("bike.xml"); JAXBContext jaxbContext = JAXBContext.newInstance(Bike.class); 解组器 jaxbUnmarshaller = jaxbContext.createUnmarshaller(); JAXBElement je1 = jaxbUnmarshaller.unmarshal(xml, Bike.class); 自行车自行车 = je1.getValue(); if (bike.color == null && bike.vin == null && bike.engineCapacity == null) { System.out.println("遗留 XML"); 文档 doc = Bike.readXml(xml); doc.getDocumentElement().normalize(); NodeList nList = doc.getElementsByTagName("void"); 字符串颜色=空; 整数 vin = null; 整数引擎容量=空; 节点列表 k; for (int temp = 0; temp 0) { 颜色 = k.item(0).getTextContent(); } } 别的 { k = eElement.getElementsByTagName("int"); 如果 (k.getLength() > 0) { 如果(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) { 自行车=新自行车(vin,engineCapacity,颜色); Marshaller m = jaxbContext.createMarshaller(); m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); System.out.println("这将是新创建的 XML"); System.out.println("--------------"); m.marshal(自行车,System.out); System.out.println("--------------"); System.out.println(自行车); } } 别的 { System.out.println(自行车); } } 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()); 返回 db.parse(is2); } } 类 NullResolver 实现 EntityResolver { @覆盖 公共 InputSource resolveEntity(String publicId, String systemId) 抛出 SAXException,IOException { return new InputSource(new StringReader("")); } }

    【讨论】:

    • 感谢 gtgaxiola 的建议。但是会有性能问题吗?由于我们多次处理同一个 xml 文档。我有一个包含 10000 条自行车数据的 xml。 java.beans.XMLDecoder 呢
    • public static void main(String[] args) throws FileNotFoundException { FileInputStream fis = new FileInputStream("bike.xml"); BufferedInputStream bis = new BufferedInputStream(fis); XMLDecoder xmlDecoder = new XMLDecoder(bis); Bike mb = (Bike) xmlDecoder.readObject(); System.out.println(mb);}
    猜你喜欢
    • 2011-08-09
    • 1970-01-01
    • 2011-12-12
    • 2013-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多