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



我在使用JAXB取消编组简单XML(CSDL的子集)时遇到问题
有人过去曾试图帮助我(在这里),但部分成功了,我不知道该怎么办…
请考虑以下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>

有人告诉我,我有一个软件包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.*;

此外,我还有以下数据结构:

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

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 {
  ....
}

注意:在Schema.java中,我有一些与XML无关的实现,所以我去掉了它(内部逻辑)

在使用JAXB取消组织XML后,返回的Edmx对象在"schema"one_answers"version"成员中都包含null值,尽管我在包info.java中提到了所有xmlns参数。

有人吗?:(

更新

在我对你之前的一个问题的回答中,我提供了这个问题的模型映射。

  • 尝试用JAXB解组EDMX时出错

我已经更新了这个答案,以解决您的以下评论:

我为什么要申报'namespace=schemas.microsoft.com/ado/2009/11/edm';在我的@XmlElement中?很抱歉让人讨厌(这是我第一次使用JAXB),但我只是有一个长的XML,其中有许多@XmlElement节点,类似于"Schema"和我只想为它们声明命名空间一旦

通过根据模型类对应的名称空间将它们组织到不同的包中,可以减少需要声明名称空间的次数。

命名空间http://schemas.microsoft.com/ado/2007/06/edmx的包1

包裹信息

对于每个包,我们将使用@XmlSchema注释来指定命名空间限定。在这个例子中,我们只需要指定这个特定包的名称空间。

@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

对应于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

DataService类包含对与不同XML名称空间相对应的类的引用。如果Schema类在同一个包中,我们可以使用@XmlElement注释来覆盖命名空间限定。由于Schema在不同的包中,我们可以使用@XmlElementRef注释。这个命令告诉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;
    }
}

命名空间http://schemas.microsoft.com/ado/2009/11/edm的包2

我们将再次使用@XmlSchema来声明第二个包的名称空间信息。

包裹信息

@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类中的元素将是基于其包的@XmlSchema注释中的命名空间信息的命名空间限定的。

package forum14875956.schema;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name="Schema")
public class Schema {
}

原始答案

您需要在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;
    }
 }

完整示例

不久前,我回答了你的一个问题,为这个模型提供了一个完整的映射:

  • 尝试用JAXB解组EDMX时出错

最新更新