【问题标题】:How do you implement simple un/marshalling for xml?你如何为 xml 实现简单的 un/marshalling?
【发布时间】:2015-08-28 19:43:23
【问题描述】:

我正在尝试使用 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);
    }
}

【问题讨论】:

    标签: java xml jaxb marshalling unmarshalling


    【解决方案1】:

    基本上,这里有一个大小写问题 - 在 XML 文件中,所有标记都以大写字母开头。在 Java 类中,您已使用 @XmlElement 注释设置器,从而指示 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;
            }
        }
    

    【讨论】:

    • 当我在上面运行你的代码时,它工作得很好。但是当我开始换出 xml 标记名称(例如“Value1”)时,我又遇到了奇怪的异常。当我更改所有 xml 标记名称以完全匹配 propOrder 中的值时,它现在正在工作。但奇怪的是,在上面的代码中,它使用了 xml,它在 xml 和 propOrder 之间存在不匹配的情况,并且它工作得很好。无论如何,谢谢!
    • 请注意,@XmlTypeannotation 中的propOrder 的名称与 XML 文件中的名称不对应,而是与 Java 类中的属性相对应。由于您使用的是基于属性的访问,它们必须对应于 getter/setter 的名称
    【解决方案2】:

    课堂位置使用

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

    在课堂地点

    @XmlRootElement(name = "Locations")
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-08
      • 1970-01-01
      • 2019-09-19
      • 2021-12-01
      • 1970-01-01
      • 2018-05-07
      • 2011-02-03
      • 2012-09-19
      相关资源
      最近更新 更多