2014-09-09 3 views
2

Я использую JAXB для развязывания XML-файла.JAXB unmarshal mystery XML

Все, что я знаю о файле XML, это то, что оно является действительным XML.

Как тогда я должен указать класс и/или пакет newInstance?

JAXBContext jaxbContext = JAXBContext.newInstance(??????); 
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); 
Object o = (Object) unmarshaller.unmarshal(myFile); 

Я ничего не видел в docs, что решить эту проблему.

+0

Но, как часто, действительно интересный момент: зачем вам его развязывать? Если вы не знаете, какие данные он содержит: как вы предлагаете его обрабатывать каким-либо нетривиальным способом? - EVen unmarshalling в родовое дерево DOM потребует, чтобы у вас было какое-то представление о том, что * у вас есть, чтобы разрешить что-либо, кроме восхождения деревьев. – laune

ответ

4

Вам нужно сообщить JaxB, какой класс следует отменить, чтобы он мог использовать аннотации в классе для решения иерархии xml. Вам нужно будет иметь класс, который также аннотируется с чем-то вроде @XmlRootElement. Если вы хотите проанализировать произвольный xml, вам, вероятно, понадобится что-то сделать с DocumentBuilder или xpath.

Посмотрите это artical для получения дополнительной информации.

http://blog.bdoughan.com/2012/11/creating-generic-list-wrapper-in-jaxb.html

я использовал что-то вроде этого, чтобы преобразовать произвольный XML в классе. Любое поле фактически будет списком org.w3c.dom.Element, в котором вы можете получить информацию.

http://docs.oracle.com/javase/7/docs/api/org/w3c/dom/Element.html

@XmlRootElement 
class Wrapper { 
     /** 
     * Everything else 
     */ 
     @Transient 
     @XmlAnyElement(lax = true) 
     private List<Element> any; 


     public List<Element> getAny() { 
      return any; 
     } 

} 
+0

Итак, единственная альтернатива тогда НЕ использовать JAXB в моем случае? – Josh

+0

С сериализацией jaxb вам действительно нужно знать, что такое источник и место назначения. Существует решение, которое я использовал для unserialize произвольных xml-данных, но он не дает вам пригодных для использования объектов. Вы можете использовать @XmlAnyElement (lax = true), который будет использоваться в любом типе xml, и он преобразует его в список .dom.Element, который вы можете проанализировать, но это не собирается вас много покупать. Вам все равно нужно иметь класс, у которого есть поле типа @XmlAnyElement, и вы должны использовать этот класс в качестве аргумента newInstance. –

0

В newInstance необходимо добавить корневой класс элемент, отображающих ваш XML ... ниже пример

Вот пример ..

public static void main(String[] args) throws JAXBException { 
     final JAXBContext context = JAXBContext.newInstance(Vehicals.class); 
     final Marshaller m = context.createMarshaller(); 
     m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 

     final Vehicals vehicals = new Vehicals(); 

     List<Car> cars = new ArrayList<Car>(); 
     Car c = new Car(); 
     c.setName("Mercedes"); 
     cars.add(c); 

     c = new Car(); 
     c.setName("BMW"); 
     cars.add(c); 

     vehicals.setCar(cars); 

     m.marshal(vehicals, System.out); 
    } 

Vehicals. java

import java.util.List; 

import javax.xml.bind.annotation.XmlRootElement; 

    @XmlRootElement 
    public class Vehicals { 

     private List<Car> Car; 

     public List<Car> getCar() { 
      return Car; 
     } 

     public void setCar(List<Car> cars) { 
      this.Car = cars; 
     } 
    } 

Car.java

import javax.xml.bind.annotation.XmlRootElement; 
import javax.xml.bind.annotation.XmlTransient; 

@XmlRootElement 
public class Car { 

    @XmlTransient 
    private Long id; 

    private String name; 

    @XmlTransient 
    private String code; 


    public Long getId() { 
     return id; 
    } 
    public void setId(Long id) { 
     this.id = id; 
    } 
    public String getName() { 
     return name; 
    } 
    public void setName(String name) { 
     this.name = name; 
    } 
    public String getCode() { 
     return code; 
    } 
    public void setCode(String code) { 
     this.code = code; 
    } 
} 

output.xml

<Vehicle> 
    <Car> 
     <name>Mercedes</name> 
     </Car> 
    <Car> 
     <name>BMW</name> 
    </Car> 
</Vehicle> 

Для распаковать это то же самое. В моем случае я добавил параметр Vehicals в качестве параметра в метод newInstance.

+0

Спасибо за ответ, но я не вижу, как это помогает мне? вы все еще проходите в Vehicals.class до newInstance. – Josh

Смежные вопросы