简体   繁体   English

使用JAXB取消使用namspace编组XML时的空值

[英]Null values while un-marshalling XML with namspaces using JAXB

I have an issue while un-marshalling simple XML (a subset of CSDL) using JAXB. 使用JAXB取消编组简单XML(CSDL的子集)时遇到问题。
Someone already tried to assist me in the past ( here ), however it is partially worked and I don't know what to do... 过去( 这里 )已经有人尝试为我提供帮助,但是它部分起作用,我不知道该怎么办...
Please consider the following XML: 请考虑以下XML:

<edmx:Edmx xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx">
  <edmx:DataServices xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" m:DataServiceVersion="3.0">
    <Schema xmlns:cg="http://schemas.microsoft.com/ado/2006/04/codegeneration" xmlns:sap="http://www.sap.com/Protocols/SAPData" xmlns="http://schemas.microsoft.com/ado/2009/11/edm" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" Namespace="myNS">
    </Schema>
  </edmx:DataServices>
</edmx:Edmx>

As I was told, I have a package-info.java file that looks like (in the same package): 有人告诉我,我有一个package-info.java文件,看起来像(在同一软件包中):

@XmlSchema(
  namespace="http://schemas.microsoft.com/ado/2007/06/edmx",
  elementFormDefault=XmlNsForm.QUALIFIED,
  xmlns={
          @XmlNs(prefix="edmx", namespaceURI="http://schemas.microsoft.com/ado/2007/06/edmx"),
          @XmlNs(prefix="", namespaceURI="http://schemas.microsoft.com/ado/2009/11/edm"),
          @XmlNs(prefix="m", namespaceURI="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata")                                
  }
)
@XmlAccessorType(XmlAccessType.FIELD)
package com.sap.ndb.studio.rdl.csdlparser.jaxb.objects;

import javax.xml.bind.annotation.*;

In addition, I have the following data structure: 另外,我具有以下数据结构:

Edmx.java Edmx.java

package com.sap.ndb.studio.rdl.csdlparser.jaxb.objects;

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

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

    @XmlElement(name = "DataServices")
    private DataService dataService;

    public DataService getDataService() {
          return dataService;
    }
}

DataService.java DataService.java

package com.sap.ndb.studio.rdl.csdlparser.jaxb.objects;

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

@XmlRootElement
public class DataService {

    @XmlElement(name = "Schema")
    private Schema schema;

    @XmlAttribute(name = "DataServiceVersion")
    private double version;

    public Schema getSchema() {
      return schema;
    }
 }

Schema.java 模式

package com.sap.ndb.studio.rdl.csdlparser.jaxb.objects;

@XmlRootElement
public class Schema {
  ....
}

Notice: in Schema.java I have some implementation which does not related to the XML so I have took it off (internal logic). 注意:在Schema.java中,我有一些与XML不相关的实现,因此我将其取消(内部逻辑)。

After un-marshalling the XML using the JAXB, The returned Edmx object contains null values both in 'schema' and 'version' members, although I have mentioned all xmlns parameters in my package-info.java. 使用JAXB解组XML之后,返回的Edmx对象在'schema'和'version'成员中都包含空值,尽管我在package-info.java中提到了所有xmlns参数。

Anyone? 任何人? :( :(

UPDATE UPDATE

In my answer to one of your previous questions I provider a mapping for the model from this question. 在回答您先前的一个问题时,我提供了该问题的模型映射。

I have updated this answer to address the following comment that you made: 我已经更新了此答案,以解决您的以下评论:

Why should I declare 'namespace=schemas.microsoft.com/ado/2009/11/edm'; 为什么要声明“ namespace = schemas.microsoft.com / ado / 2009/11 / edm”; in my @XmlElement? 在我的@XmlElement中? sorry for being annoying (this is my first experience with JAXB) but I just gonna have a long XML with many @XmlElement nodes similar to the 'Schema' and I would like to declare the namespace for them only once... 抱歉,这很烦人(这是我第一次使用JAXB),但是我将拥有一个长的XML,其中包含许多类似于'Schema'的@XmlElement节点,我只想为它们声明一次名称空间...

You can reduce the number of times you need to declare a namespace by organizing your model classes into different packages based on the namespace that they correspond to. 通过将模型类根据对应的名称空间组织到不同的包中,可以减少声明名称空间的次数。

Package 1 for Namespace http://schemas.microsoft.com/ado/2007/06/edmx 命名空间的套件1 http://schemas.microsoft.com/ado/2007/06/edmx

package-info 包装信息

For each package we will use the @XmlSchema annotation to specify the namespace qualification. 对于每个包,我们将使用@XmlSchema批注指定名称空间限定。 In this example we only need to specify the namespace for this particular package. 在此示例中,我们只需要为此特定程序包指定名称空间。

@XmlSchema(
        namespace="http://schemas.microsoft.com/ado/2007/06/edmx",
        elementFormDefault=XmlNsForm.QUALIFIED,
        xmlns={
                @XmlNs(
                    prefix="edmx", 
                    namespaceURI="http://schemas.microsoft.com/ado/2007/06/edmx"
                ),
        }
)
@XmlAccessorType(XmlAccessType.FIELD)
package forum14875956.edmx;

import javax.xml.bind.annotation.*;

Edmx 埃德克斯

The XML elements corresponding to the Edmx class will be namespace qualified according to what we defined on the @XmlSchema annotation for this package. Edmx类相对应的XML元素将根据我们在此包的@XmlSchema批注中定义的名称进行命名空间限定。

package forum14875956.edmx;

import javax.xml.bind.annotation.*;

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

    @XmlElement(name = "DataServices")
    private DataService dataService;

    public DataService getDataService() {
        return dataService;
    }

}

DataService 数据服务

The DataService class contains a reference to a class corresponding to a different XML namespace. DataService类包含对与其他XML名称空间相对应的类的引用。 If the Schema class was in the same package we could use the @XmlElement annotation to override the namespace qualification. 如果Schema类位于同一包中,则可以使用@XmlElement批注覆盖名称空间限定。 Since Schema is in a different package we can use the @XmlElementRef annotation. 由于Schema位于不同的程序包中,因此我们可以使用@XmlElementRef批注。 This tells JAXB to derive the element information from the root element configured for that class. 这告诉JAXB从为该类配置的根元素中得出元素信息。

package forum14875956.edmx;

import javax.xml.bind.annotation.*;
import forum14875956.schema.Schema;

public class DataService {

    //@XmlElement(namespace="http://schemas.microsoft.com/ado/2009/11/edm", name="Schema")
    @XmlElementRef
    private Schema schema;

    public Schema getSchema() {
        return schema;
    }

}

Package 2 for Namespace http://schemas.microsoft.com/ado/2009/11/edm 命名空间的套件2 http://schemas.microsoft.com/ado/2009/11/edm

Again we will use the @XmlSchema to declare the namespace information for the second package. 同样,我们将使用@XmlSchema声明第二个包的名称空间信息。

package-info 包装信息

@XmlSchema(
        namespace="http://schemas.microsoft.com/ado/2009/11/edm",
        elementFormDefault=XmlNsForm.QUALIFIED,
        xmlns={
                @XmlNs(
                    prefix="", 
                    namespaceURI="http://schemas.microsoft.com/ado/2009/11/edm"
                )
        }
)
@XmlAccessorType(XmlAccessType.FIELD)
package forum14875956.schema;

import javax.xml.bind.annotation.*;

Schema 架构图

The elements in the Schema class will be namespace qualified based namespace information in the @XmlSchema annotation for its package. Schema类中的元素将是其程序包的@XmlSchema批注中基于名称空间限定的名称空间信息。

package forum14875956.schema;

import javax.xml.bind.annotation.XmlRootElement;

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

}

ORIGINAL ANSWER 原始答案

You need to include the namespace URI on the mapping for the schema property: 您需要在schema属性的映射上包括名称空间URI:

@XmlRootElement
public class DataService {

    @XmlElement(name = "Schema" , namespace="http://schemas.microsoft.com/ado/2009/11/edm")
    private Schema schema;

    @XmlAttribute(name = "DataServiceVersion")
    private double version;

    public Schema getSchema() {
      return schema;
    }
 }

Full Example 完整的例子

A little while I ago I answered one of your questions providing a complete mapping for this model: 不久前,我回答了您的一个问题,为该模型提供了完整的映射:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM