我在使用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时出错