2

使用 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>

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

另外,我有以下数据结构:

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;
    }
}

数据服务.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;
    }
 }

架构.java

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

@XmlRootElement
public class Schema {
  ....
}

注意:在 Schema.java 中,我有一些与 XML 无关的实现,所以我将其删除(内部逻辑)。

使用 JAXB 解组 XML 后,返回的 Edmx 对象在“schema”和“version”成员中都包含空值,尽管我在 package-info.java 中提到了所有 xmlns 参数。

任何人?:(

4

1 回答 1

0

更新

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

我已更新此答案以解决您提出的以下评论:

为什么我要声明'namespace=schemas.microsoft.com/ado/2009/11/edm';在我的@XmlElement 中?很抱歉很烦人(这是我第一次使用 JAXB),但我将有一个很长的 XML,其中包含许多类似于“架构”的 @XmlElement 节点,我只想为它们声明一次命名空间......

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

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

包信息

对于每个包,我们将使用@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

与该类对应的 XML 元素Edmx将根据我们在@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包含对对应于不同 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;
    }

}

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

我们将再次使用@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;
    }
 }

完整示例

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

于 2013-02-21T15:18:38.830 回答