gpt4 book ai didi

java - 使用 JAXB 使用 namspaces 解码 XML 时为空值

转载 作者:行者123 更新时间:2023-11-29 09:06:03 24 4
gpt4 key购买 nike

我在使用 JAXB 解码简单 XML(CSDL 的子集)时遇到问题。
过去已经有人试图帮助我 ( here ),但是它部分起作用了,我不知道该怎么做...
请考虑以下 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;
}
}

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 对象在“模式”和“版本”成员中都包含空值,尽管我已经在我的 package-info.java 中提到了所有 xmlns 参数。

任何人? :(

最佳答案

更新

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

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

Why should I declare 'namespace=schemas.microsoft.com/ado/2009/11/edm'; in my @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...

您可以根据模型类对应的命名空间将模型类组织到不同的包中,从而减少声明命名空间所需的次数。

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

包信息

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

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

}

命名空间包 2 http://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;
}
}

完整示例

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

关于java - 使用 JAXB 使用 namspaces 解码 XML 时为空值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15005640/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com