【问题标题】:JAXB Unmarshalling using XMLSchema not working with several namespaces使用 XMLSchema 的 JAXB 解组不适用于多个命名空间
【发布时间】:2015-11-18 06:19:49
【问题描述】:

我一直在寻找有关如何使用 package-info.java 文件上的注释 @XMLSchema 来实现 Unmarshalling 的示例。

我的理解是该理论假设非常简单。但是,查看以下链接后,我仍然不明白为什么注释不起作用。

代码如下:

包信息.java:

@XmlSchema(
    namespace="http://test.org/url1",
    elementFormDefault = XmlNsForm.QUALIFIED,
    attributeFormDefault = javax.xml.bind.annotation.XmlNsForm.UNQUALIFIED,
    xmlns={
       @XmlNs(prefix="ns6",         namespaceURI="http://test.org/url6"),
       @XmlNs(prefix="ns5",         namespaceURI="http://test.org/url5"), 
       @XmlNs(prefix="ns7",         namespaceURI="http://test.org/url7"), 
       @XmlNs(prefix="ns1",         namespaceURI="http://test.org/url1"), 
       @XmlNs(prefix="ns3",         namespaceURI="http://test.org/url3"), 
       @XmlNs(prefix="ns2",         namespaceURI="http://test.org/url2"), 
       @XmlNs( prefix="ns4",        namespaceURI="http://test.org/url4"),          
   }
)
package simpleJAXB;
import javax.xml.bind.annotation.*;

用作输入的 XML:

<?xml version="1.0" encoding="UTF-8"?>
<ns6:RequestShort 
    xmlns:ns2="http://test.org/url2" 
    xmlns:ns1="http://test.org/url1" 
    xmlns:ns4="http://test.org/url4" 
    xmlns:ns3="http://test.org/url3" 
    xmlns:ns5="http://test.org/url5" 
    xmlns:ns6="http://test.org/url6" 
    xmlns:ns7="http://test.org/url7">
    <ns3:IndividualRequestShort>
        <ns2:Person>Name1</ns2:Person>
        <ns2:Title>TEST</ns2:Title>
    </ns3:IndividualRequestShort>
    <ns3:IndividualRequestShort>
        <ns2:Person>Name2</ns2:Person>
        <ns2:Title>TEST2</ns2:Title>
    </ns3:IndividualRequestShort>
</ns6:RequestShort> 

这里也是类:

RequestShort:

package simpleJAXB;
import java.util.ArrayList;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement ( name = "RequestShort")
public class RequestShort {


ArrayList<IndividualRequestShort> individualRequestListShort;

public RequestShort(){}

@XmlElement(name = "IndividualRequestShort", type=IndividualRequestShort.class) 
public ArrayList<IndividualRequestShort> getIndividualRequestListShort() {
    return individualRequestListShort;
}

public void setIndividualRequestListShort(
        ArrayList<IndividualRequestShort> individualRequestList) {
    this.individualRequestListShort = individualRequestList;
}   
}

IndividualRequestShort:

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

@XmlRootElement (name= "IndividualRequestShort")
public class IndividualRequestShort {

String title;   
String person;

public IndividualRequestShort(){}

@XmlElement(name = "Title")
public String getTitle() {
    return title;
}

public void setTitle(String title) {
    this.title = title;
}

@XmlElement(name = "Person")
public String getPerson() {
    return person;
}

public void setPerson(String person) {
    this.person = person;
}

最后,主要的void方法是:

try{
        File file = new File("XML_test.xml");

        JAXBContext jaxbContext = JAXBContext.newInstance(RequestShort.class);

        Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
        RequestShort requestShort = (RequestShort) jaxbUnmarshaller.unmarshal(file);

        ArrayList<IndividualRequestShort> contentRequests = new ArrayList<IndividualRequestShort>();
        contentRequests = requestShort.getIndividualRequestListShort();

        if(contentRequests != null){                            
            Iterator<IndividualRequestShort> requestsIterator = contentRequests.iterator();
            IndividualRequestShort temp = null;
            while (requestsIterator.hasNext()) {            
                temp = (IndividualRequestShort)requestsIterator.next();
                System.out.println("Data: " + temp.getTitle() + temp.getPerson());      
            }


    } catch (Exception e) {
        System.out.println(e.toString() + " " + e.getStackTrace().toString());
    }

    return null;
}

我已经能够使用命名空间选项实际解析 xmlelment 和 xmlrootelement 上的 xml。但是,当我尝试放置 xmlschema 注释时,如上所示,我收到以下错误:

    Classes known to this context:
[B
boolean
byte
char
com.sun.xml.internal.bind.api.CompositeStructure
double
float
int
java.awt.Image
java.io.File
java.lang.Boolean
java.lang.Byte
java.lang.Character
java.lang.Class
java.lang.Double
java.lang.Float
java.lang.Integer
java.lang.Long
java.lang.Object
java.lang.Short
java.lang.String
java.lang.Void
java.math.BigDecimal
java.math.BigInteger
java.net.URI
java.net.URL
java.util.Calendar
java.util.Date
java.util.GregorianCalendar
java.util.UUID
javax.activation.DataHandler
javax.xml.bind.JAXBElement
javax.xml.datatype.Duration
javax.xml.datatype.XMLGregorianCalendar
javax.xml.namespace.QName
javax.xml.transform.Source
long
short
simpleJAXB.IndividualRequestShort
simpleJAXB.RequestShort
void

我在这里遗漏了什么吗?可以给个提示吗?

提前谢谢你!

PS:对不起,我问的这么简单,但我正在学习这个 JAXB 框架。

问候!

【问题讨论】:

    标签: java xml jaxb unmarshalling


    【解决方案1】:

    @XmlRootElement 和 @XmlElement 都具有 namespace 属性。如果未定义,则使用 package-info.java 中定义的包的命名空间。

    由于您没有指定属性,因此您的所有元素都属于命名空间http://test.org/url1。

    【讨论】:

    • 那么,如何利用里面的命名空间数组呢?我认为既然在注释( xmlns={...} )中,这些将被采用。如果不是这样,那么这个特定选项的目的是什么?
    • @Ageous 在RequestShort 元素上预先声明命名空间,这样它们就不必在使用的地方重复。尝试运行和不运行以查看差异(一旦你开始工作)。
    • 其实,在我发这个之前,我在 XMLRootElement 和 XMLElement 上使用了命名空间属性。那行得通。但是,我认为使用 XMLSchema 可以让我把所有东西放在一个地方,而不是放在我的所有类中。我发布的只是我的 xml 的简化版本。真正的会拥有更多。这就是为什么我想把 1 个包含所有命名空间的文件放在一起,易于维护。但是,如果这是不可能的,如果我总是必须使用命名空间属性,我看不出 Xmlschema 中 Xmlns 的目的是什么。
    • @Ageous 我会说一般的良好做法是将不同名称空间的类放入不同的包中。这就是 Schema-to-Java 生成器的工作原理。在这种情况下,您仍然只需要在 package-info.java 中声明名称空间,您只会拥有更多的名称空间。
    猜你喜欢
    • 1970-01-01
    • 2014-11-07
    • 1970-01-01
    • 2021-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-24
    相关资源
    最近更新 更多