2013-12-01 3 views
2

Я пытаюсь распаковать в XML-файл со следующей структурой:JAXB - демаршаллизации в XML-файл

<?xml version="1.0" encoding="UTF-8"?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
<xs:element name="map"> 
    <xs:complexType> 
     <xs:sequence> 
      <xs:element name="country" maxOccurs="unbounded"> 
       <xs:complexType> 
        <xs:sequence> 
         <xs:element name="name" type="xs:string" /> 
         <xs:element name="x" type="xs:integer" /> 
         <xs:element name="y" type="xs:integer" /> 
        </xs:sequence> 
       </xs:complexType> 
      </xs:element> 
     </xs:sequence> 
     <xs:attribute name="name" type="xs:string" use="required" /> 
    </xs:complexType> 
</xs:element> 

пример является:

<?xml version="1.0" encoding="UTF-8"?> 

<map name="usa" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:noNamespaceSchemaLocation="field.xsd"> 
<country> 
    <name>Test1</name> 
    <x>110</x> 
    <y>20</y> 
</country> 
<country> 
    <name>Test2</name> 
    <x>200</x> 
    <y>30</y> 
</country> 
<country> 
    <name>Test3</name> 
    <x>350</x> 
    <y>80</y> 
</country> 
</map> 

и я создал следующий классов для этого:

package game.view.gui; 

public class ObjectFactory { 

    public ObjectFactory() { 
    } 

    public Map createMap() { 
     return new Map(); 
    } 
} 

и

package game.view.gui; 

import java.util.ArrayList; 
import java.util.List; 

import javax.xml.bind.annotation.XmlAccessType; 
import javax.xml.bind.annotation.XmlAccessorType; 
import javax.xml.bind.annotation.XmlAttribute; 
import javax.xml.bind.annotation.XmlElement; 
import javax.xml.bind.annotation.XmlRootElement; 

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlRootElement(name = "map") 
public class Map { 
@XmlAttribute 
private String name; 
private List<Country> countries = new ArrayList<Country>(); 

@XmlElement(name = "country") 
public List<Country> getCountries() { 
    return countries; 
} 

public void setCountries(List<Country> countries) { 
    this.countries = countries; 
} 
} 

и

package game.view.gui; 

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

@XmlRootElement(name = "country") 
public class Country { 
    @XmlElement(required = true) 
    private String name; 
    @XmlElement(required = true) 
    private int x; 
    @XmlElement(required = true) 
    private int y; 

    public String getName() { 
     return name; 
    } 

    public int getX() { 
     return x; 
    } 

    public int getY() { 
     return y; 
    } 
} 

Я всегда получаю исключение, в котором кажется, что XML не подходит для созданных POJOs. Я попытался сделать это в равной степени в учебнике, которое я прочитал. Исключение появляется в этой строке кода:

Map map = (Map) unmarsh.unmarshal(file); 

Можете ли вы рассказать, что мне нужно изменить в pojos, что все работает?

Edit1: Исключение:

javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"map"). Expected elements are (none) 
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(Unknown Source) 
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Unknown Source) 
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Unknown Source) 
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Unknown Source) 
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext$DefaultRootLoader.childElement(Unknown Source) 
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(Unknown Source) 
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(Unknown Source) 
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.startElement(Unknown Source) 
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(Unknown Source) 
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source) 
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl$NSContentDriver.scanRootElementHook(Unknown Source) 
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(Unknown Source) 
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(Unknown Source) 
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source) 
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(Unknown Source) 
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source) 
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source) 
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source) 
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source) 
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source) 
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source) 
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(Unknown Source) 
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(Unknown Source) 
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(Unknown Source) 
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(Unknown Source) 
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(Unknown Source) 
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(Unknown Source) 
+0

Вы должны включить исключение в свой вопрос. – kjhughes

+0

Хорошо. Не был уверен, что это необходимо. – baxbear

+1

Как вы создали «JAXBContext»? –

ответ

1

В созданном классе ObjectFactory отсутствует требуемая аннотация @XmlRegistry. Без этой аннотации ObjectFactory будет рассматриваться как обычный объект домена.

+0

Да, это сработало. Но теперь я получаю исключение: 1 счетчик IllegalAnnotationExceptions Класс имеет два свойства с одним и тем же названием «страны» - но я не могу найти свойство второй страны - или, может быть, я просто не понимаю исключения – baxbear

+0

@baxbear - По умолчанию JAXB ожидает, аннотации для свойства (метод get или set). Если вы аннотируете поле, вы должны указать '@XmlAccessorType (XmlAccessType.FIELD)' в классе: http://blog.bdoughan.com/2011/06/using-jaxbs-xmlaccessortype-to.html –

2

При создании JAXBContext (который используется для создания маршаллера и unmarshaller экземпляров), вам необходимо пройти корневые классы вашей схемы - как правило, они будут помечены @XmlType и/или @XmlRootElement - чтобы контекст знал, с какими классами он работает. То, что он не делает, - это выключить и отсканировать все классы в вашем пути к классу, вне зависимости от того, что у них может быть что-то актуальное; это было бы очень дорого!

Практически изменение:

JAXBContext.newInstance(); 

к:

JAXBContext.newInstance(Map.class); 

Вам также может потребоваться указать отображение пространства имен (для пустого пространства имен) в явном виде в аннотации (например, через namespace поле аннотаций @XmlRootElement), и я считаю, что самый простой способ отладки контекстов JAXB часто заключается в создании схем, которые они кодируют с помощью своего метода generateSchema (с фиктивным выходным резольвером, который просто заставляет их сбрасывать t o System.out ...)

+0

Я обнаружил, что могу _exactly_ воспроизвести сообщение об ошибке, указанное при использовании пустого набора связанных классов. –

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