使用JAXB获取可以是任何类型的内容和标记XML的属性

时间:2014-12-23 13:31:12

标签: java xml jaxb

使用jaxb时,我遇到了一个问题,即使用“object”类型映射标记的内容 我有一个名为“attribute”的标签,在这个标签中,我有一个属性“type”。这个标签的内容可以是任何类型,我想得到这个标签的“type”属性和我创建Value类的原因,除了当我把XmlValue注释放在字段“content”上时,我有一个NullPointerException

我的XML:

<attribute>
    <id>9137755520013147917</id>
    <name>Routeur</name>
    <value xsi:type="EntityType" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <id>9139898058113224747</id>
        <name>pe-cdg1200e-2sn311-01</name>
        <objectTypeId>9138560130813318972</objectTypeId>
        <objectTypeName>Routeur PE</objectTypeName>
        <classId>3061830882013808530</classId>
        <className>Elément de Réseau</className>
    </value>
</attribute>

我的标记属性,可以包含任何类型的内容

Attribute.java

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "id",
    "name",
    "ismultiple",
    "type",
    "value"
})
public static class Attribute {

    @XmlElement(required = true)
    protected BigInteger id;
    protected String name;
    protected String ismultiple;
    protected String type;
    @XmlElement(required = true)
    protected Value value;

Value.java

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "")
public class Value {

public Value() {
}

@XmlAttribute(namespace="http://www.w3.org/2001/XMLSchema-instance")
private String type;

@XmlValue
private Object value ;

//getter setter

我有这个错误:

Exception in thread "main" java.lang.NullPointerException
at com.sun.xml.internal.bind.v2.runtime.reflect.TransducedAccessor.get(TransducedAccessor.java:154)
at com.sun.xml.internal.bind.v2.runtime.property.ValueProperty.<init>(ValueProperty.java:66)
at com.sun.xml.internal.bind.v2.runtime.property.PropertyFactory.create(PropertyFactory.java:95)
at com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.<init>(ClassBeanInfoImpl.java:145)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:479)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:498)
at com.sun.xml.internal.bind.v2.runtime.property.SingleElementNodeProperty.<init>(SingleElementNodeProperty.java:90)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at com.sun.xml.internal.bind.v2.runtime.property.PropertyFactory.create(PropertyFactory.java:113)
at com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.<init>(ClassBeanInfoImpl.java:145)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:479)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:498)
at com.sun.xml.internal.bind.v2.runtime.property.ArrayElementProperty.<init>(ArrayElementProperty.java:97)
at com.sun.xml.internal.bind.v2.runtime.property.ArrayElementNodeProperty.<init>(ArrayElementNodeProperty.java:47)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at com.sun.xml.internal.bind.v2.runtime.property.PropertyFactory.create(PropertyFactory.java:113)
at com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.<init>(ClassBeanInfoImpl.java:145)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:479)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:498)
at com.sun.xml.internal.bind.v2.runtime.property.SingleElementNodeProperty.<init>(SingleElementNodeProperty.java:90)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at com.sun.xml.internal.bind.v2.runtime.property.PropertyFactory.create(PropertyFactory.java:113)
at com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.<init>(ClassBeanInfoImpl.java:145)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:479)
at com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.<init>(ClassBeanInfoImpl.java:132)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:479)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:305)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1100)
at com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:143)
at com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:110)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:202)
at javax.xml.bind.ContextFinder.find(ContextFinder.java:376)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:574)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:522)
at test.JAXB.main(JAXB.java:25)

公共类JAXB {

/**
 * @param args
 * @throws JAXBException
 */
public static void main(String[] args) throws JAXBException {
    File xmlFile = new File("C:\\activation.xml");

    //JAXBContext jaxbContext = JAXBContext.newInstance(ObjectFactory.class);
    JAXBContext jaxbContext = JAXBContext.newInstance(ServiceOrderType.class);

    Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
    ServiceOrderType scf = (ServiceOrderType) jaxbUnmarshaller.unmarshal(xmlFile);
    System.out.println(scf);

    for (Attribute attribute : scf.getAttributes().getAttribute()) {

        if (attribute.getName().equals("RESEAU SERVEUR XML")) {

            /*if (attribute.getValue() instanceof EntityListType){
             EntityListType reseau = (EntityListType) attribute.getValue();
             System.out.println( "name: " + reseau.getEntity().get(0).getName());
             //Element content  = (Element) attribute.getValue();
             //System.out.println(content.getAttributes().toString());

             }*/
            System.out.println("value type: " + attribute.getValue().getType());

            //List<EntityType> reseau = (List<EntityType>) attribute.getValue;
            EntityListType reseau = (EntityListType) attribute.getValue().getObject();
            System.out.println("*******>" + reseau.getEntity().get(0).getName());
        // Object ob = attribute.getValue().getObject();

            System.out.println(attribute.getName() + "---------------->" + attribute.getValue().getObject());
        }
    }
    /*
     for(Attribute attribute :  scf.getComponents().getEntity().get(0).getAttributes().getAttribute()){

     if(attribute.getName().equals("RESEAU SERVEUR XML")){

     System.out.println(attribute.getName() + "---------------->" + attribute.getValue());
     //System.out.println(attribute.getValue().get);
     }
     }*/
}

1 个答案:

答案 0 :(得分:0)

首先,您必须将Value指定为RootElement。由于它包含许多子节点,因此您必须将其内容指定为对象数组。您无法使用@XmlValue,必须使用@XmlAnyElement(lax=true)

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "")
class Value {

    @XmlAttribute(namespace="http://www.w3.org/2001/XMLSchema-instance")
    private String type;

    @XmlAnyElement(lax=true) 
    private Object[] body;

    public String getType() {
        return type;
    }


    public Object[] getBody() {
        return body;
    }
}

然后为了得到一个字符串表示,你就像这样做

Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

StringWriter sw = new StringWriter();
jaxbMarshaller.marshal(example.getAttributes().get(0).getValue(), sw);
System.out.println(sw.toString());

当然,如果您有多个Value元素,则必须进行迭代,但这适用于您提供的示例。

在这里了解更多信息http://blog.bdoughan.com/2010/08/using-xmlanyelement-to-build-generic.html