你如何为xml实现简单的un / marshalling?

时间:2015-08-28 19:43:23

标签: java xml jaxb marshalling unmarshalling

我尝试使用Java为我的xml文件创建一个简单的un / marshalling。我在网上找到了一些很好的例子并试图遵循它们,但它并不适合我。以下是两个实现与我想要的非常类似的链接: http://www.mkyong.com/java/jaxb-hello-world-example/convert xml to java object using jaxb (unmarshal)

当我运行我的代码时,我得到了这个:

Exception in thread "main" com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 6 counts of IllegalAnnotationExceptions
Property value1 is present but not specified in @XmlType.propOrder
this problem is related to the following location:
    at public java.lang.String Location.getValue1()
    at Location
    at public java.util.List Locations.getLocation()
    at Locations
Property value2 is present but not specified in @XmlType.propOrder
this problem is related to the following location:
    at public int Location.getValue2()
    at Location
    at public java.util.List Locations.getLocation()
    at Locations
Property value3 is present but not specified in @XmlType.propOrder
this problem is related to the following location:
    at public java.lang.String Location.getValue3()
    at Location
    at public java.util.List Locations.getLocation()
    at Locations
Property Value1 appears in @XmlType.propOrder, but no such property exists. Maybe you meant value1?
this problem is related to the following location:
    at Location
    at public java.util.List Locations.getLocation()
    at Locations
Property Value2 appears in @XmlType.propOrder, but no such property exists. Maybe you meant value2?
this problem is related to the following location:
    at Location
    at public java.util.List Locations.getLocation()
    at Locations
Property Value3 appears in @XmlType.propOrder, but no such property exists. Maybe you meant value3?
this problem is related to the following location:
    at Location
    at public java.util.List Locations.getLocation()
    at Locations

at com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:91)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:445)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:277)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:124)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1123)
at com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:147)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:247)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:234)
at javax.xml.bind.ContextFinder.find(ContextFinder.java:462)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:641)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:584)
at main.main(main.java:18)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

我的xml是这样的:

<?xml version="1.0" encoding="utf-8" ?>
<Locations>
    <Location>
        <Value1>one</Value1>
        <Value2>1</Value2>
        <Value3>a</Value3>
    </Location>
    <Location>
        <Value1>two</Value1>
        <Value2>2</Value2>
        <Value3>b</Value3>
    </Location>
    <Location>
        <Value1>three</Value1>
        <Value2>3</Value2>
        <Value3>c</Value3>
    </Location>
</Locations>

以下是我的两个对象类:

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.List;


@XmlRootElement
public class Locations {
    List<Location> location;

    @XmlElement(name="Location")
    public List<Location> getLocation() {
        return location;
    }

    public void setLocation(List<Location> myLocation) {
        this.location = myLocation;
    }
}



import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;

@XmlType(propOrder = {"Value1", "Value2", "Value3"})
public class Location {
    String Value1;
    int Value2;
    String Value3;

    public String getValue1() {
        return Value1;
    }

    @XmlElement
    public void setValue1(String Value1) {
        this.Value1 = Value1;
    }

    public int getValue2() {
        return Value2;
    }

    @XmlElement
    public void setValue2(int Value2) {
        this.Value2 = Value2;
    }

    public String getValue3() {
        return Value3;
    }

    @XmlElement
    public void setValue3(String Value3) {
        this.Value3 = Value3;
    }
}

以下是我的主要内容:

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.*;
import java.io.File;

public class main {
    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Locations.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("C:\\files\\Settings.xml");
        Locations locations = (Locations) unmarshaller.unmarshal(xml);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(locations, System.out);
    }
}

2 个答案:

答案 0 :(得分:2)

基本上,这里有一个案例问题 - 在XML文件中,标签都以大写字母开头。在java类中,您使用@XmlElement注释了setter,从而指示JAXB将这些用于编组/解组。但是,根据JavaBeans specification, Section 8.3,setter方法setValue1表示该属性名为value1(小写!)。

因此,您必须明确告诉JAXB XML中要映射到Java类属性的属性的正确名称(区分大小写!)。例如,在您的情况下,您必须告诉必须将Value1映射到Java属性value1。您可以通过使用@XmlElement(name="Value1")注释setter方法来完成此操作。 propOrder的值必须与Java类的属性相关,而不是与XML标记相关。

以下对我有用:

   public static void main(String[] args) throws JAXBException {
        JAXBContext jc = JAXBContext.newInstance(Locations.class, Location.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("D:\\temp\\Settings.xml");
        Locations locations = (Locations) unmarshaller.unmarshal(xml);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(locations, System.out);
    }

    @XmlRootElement(name = "Locations")
    private static class Locations {
        List<Location> location;

        public List<Location> getLocation() {
            return location;
        }

        @XmlElement(name = "Location")
        public void setLocation(List<Location> myLocation) {
            this.location = myLocation;
        }
    }

    @XmlType(propOrder = { "value1", "value2", "value3" })
    private static class Location {
        String Value1;
        int Value2;
        String Value3;

        public String getValue1() {
            return Value1;
        }

        @XmlElement(name = "Value1")
        public void setValue1(String Value1) {
            this.Value1 = Value1;
        }

        public int getValue2() {
            return Value2;
        }

        @XmlElement(name = "Value2")
        public void setValue2(int Value2) {
            this.Value2 = Value2;
        }

        public String getValue3() {
            return Value3;
        }

        @XmlElement(name = "Value3")
        public void setValue3(String Value3) {
            this.Value3 = Value3;
        }
    }

答案 1 :(得分:1)

课程地点使用

@XmlType(propOrder = {"value1", "value2", "value3"})

并在课程地点

@XmlRootElement(name = "Locations")

我还建议坚持使用小写首字母表示变量的Java命名约定(类名称为大写)。例如。 Value1到value1,Value2到value2,Value3到value3