#ant #xsd #jaxb #xjc
#ant #xsd #jaxb #xjc
Вопрос:
Вот мой код:
xsdFile:
<complexType name="Player">
<sequence>
<element name="Login" type="string"></element>
<element name="Passwd" type="string"></element>
</sequence>
</complexType>
<element name="Player" type="tns:Player"></element>
Build.xml:
<exec executable="${javahome}/bin/xjc" >
<arg value="-extension" />
<arg value="-b" />
<arg value="binding.xml" />
<arg value="-d" />
<arg value="${sources}" />
<arg value="-p" />
<arg value="metier" />
<arg value="Player.xsd" />
</exec>
</target>
binding.xml:
<jxb:bindings
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
jxb:extensionBindingPrefixes="xjc" elementFormDefault="qualified" attributeFormDefault="unqualified"
version="2.1">
<jxb:globalBindings>
<xjc:simple />
<xjc:serializable/>
</jxb:globalBindings>
И, наконец,:
JAXBContext context = JAXBContext.newInstance(Player.class,ObjectFactory.class);
Unmarshaller decodeur = context.createUnmarshaller();
я добавляю «xjc: simple», чтобы иметь @XmlRootElement, но возникает исключение: javax.xml.bind.Исключение UnmarshalException: неожиданный элемент (uri:»http://www.example.org/Player «
Это не сработало корректно, потому что я получил this:@XmlRootElement (имя = «Player», пространствоимен = «http://www.example.org/Player «)
Вместо просто: @XmlRootElement(name = «Player»)
Как я могу удалить это «пространство имен»?
Спасибо
Комментарии:
1. Сгенерированный код JAXB соответствует правилам квалификации пространства имен в соответствии с вашей схемой XML. Вы уверены, что хотите удалить это из сгенерированной объектной модели?
Ответ №1:
Если ваша XML-схема указывает, что соответствующие XML-документы должны иметь квалификацию пространства имен, то JAXB сгенерирует модель Java с ожидаемой квалификацией пространства имен. Ниже я опишу способ, с помощью которого вы могли бы использовать анализатор StAX, чтобы обмануть JAXB, заставив его думать, что он анализирует документ с указанием пространства имен:
Игрок
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name="Player", namespace="http://www.example.org/Player")
public class Player {
private String login;
private String passwd;
@XmlElement(name="Login", namespace="http://www.example.org/Player")
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
@XmlElement(name="Passwd", namespace="http://www.example.org/Player")
public String getPasswd() {
return passwd;
}
public void setPasswd(String passwd) {
this.passwd = passwd;
}
}
NamespaceDelegate
Мы создадим реализацию StreamReaderDelegate
. Этот делегат сообщит, что пространство имен для всех событий элемента должно быть "http://www.example.org/Player"
. Примечание: Этот трюк предполагает, что все ваши элементы имеют одинаковый URI пространства имен.
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.util.StreamReaderDelegate;
public class NamespaceDelegate extends StreamReaderDelegate {
private static String NAMESPACE = "http://www.example.org/Player";
public NamespaceDelegate(XMLStreamReader xsr) {
super(xsr);
}
@Override
public String getNamespaceURI() {
return NAMESPACE;
}
}
ДЕМОНСТРАЦИЯ
import java.io.FileInputStream;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.util.StreamReaderDelegate;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Player.class);
FileInputStream xmlStream = new FileInputStream("input.xml");
XMLInputFactory xif = XMLInputFactory.newFactory();
XMLStreamReader xsr = xif.createXMLStreamReader(xmlStream);
StreamReaderDelegate srd = new NamespaceDelegate(xsr);
Unmarshaller unmarshaller = jc.createUnmarshaller();
Player player = (Player) unmarshaller.unmarshal(srd);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(player, System.out);
}
}
input.xml
<?xml version="1.0" encoding="UTF-8"?>
<Player>
<Login>FOO</Login>
<Passwd>BAR</Passwd>
</Player>
Ответ №2:
Я просто удаляю «ObjectFactory.class » и это работает. Новый код:
JAXBContext context = JAXBContext.newInstance(Player.class);
Unmarshaller decodeur = context.createUnmarshaller();