我有一个深层的XML结构,其中包含许多没有意义的包装程序,我将它们映射到一个Java类。使用@XmlPath映射简单的数据类型是在公园里散步,但是当涉及到实际上需要自己的类的类型时,我不太确定该怎么做,尤其是当这些类型也应该放在列表中时。
我element
在将以下示例中的所有类型映射到我的Element
类时遇到问题。由于elements
包装器驻留在使用@XmlPath
I
映射的资源中,因此我不能使用@XmlElementWrapper
,否则我通常会这样做。
示例XML结构
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<s:root xsi:schemaLocation="http://www.example.eu/test ResourceSchema.xsd" xmlns:s="http://www.example.eu/test" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<s:resource>
<s:information>
<s:date>2013-07-04</s:date>
<s:name>This example does not work</s:name>
</s:information>
<s:elements>
<s:refobj>
<s:id>1</s:id>
<s:source>First Source</s:source>
</s:refobj>
<s:refobj>
<s:id>2</s:id>
<s:source>Second Source</s:source>
</s:refobj>
<s:refobj>
<s:id>5</s:id>
<s:source>Fifth Source</s:source>
</s:refobj>
</s:elements>
</s:resource>
</s:root>
根java
@XmlRootElement(name = "root")
@XmlAccessorType(XmlAccessType.FIELD)
public class Root {
@XmlPath("resource/information/date/text()")
private String date;
@XmlPath("s:resource/s:information/s:name/text()")
private String name;
@XmlPath("resource/elements/refobj")
private List<RefObj> refObjs;
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
RefObj.java
@XmlRootElement(name = "refobj")
@XmlAccessorType(XmlAccessType.FIELD)
public class RefObj {
@XmlElement(name = "id")
private int id;
@XmlElement(name = "source")
private String source;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
}
马歇尔/反马歇尔
public static void main(String[] args) {
String xml = getXML();
Root root = null;
try {
JAXBContext context = JAXBContext.newInstance(Root.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
StringReader stringReader = new StringReader(xml);
root = (Root) unmarshaller.unmarshal(stringReader);
} catch (Exception ex) {
System.err.println("Failed to unmarshal XML!");
}
try {
JAXBContext context = JAXBContext.newInstance(Root.class);
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, "http://www.example.eu/test ResourceSchema.xsd");
StringWriter stringWriter = new StringWriter();
marshaller.marshal(root, stringWriter);
System.out.println(new String(stringWriter.toString().getBytes(Charset.forName("UTF-8"))));
} catch (Exception ex) {
System.err.println("Failed to marshal object!");
}
}
包信息.java
@XmlSchema(
namespace = "http://www.example.eu/test",
attributeFormDefault = XmlNsForm.QUALIFIED,
elementFormDefault = XmlNsForm.QUALIFIED,
xmlns = {
@XmlNs(
prefix = "s",
namespaceURI = "http://www.example.eu/test")
},
location = "http://www.example.eu/test ResourceSchema.xsd")
package se.example.mavenproject1;
import javax.xml.bind.annotation.XmlNs;
import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;
我可以执行该应用程序,但是当我解组/编组XML内容时没有映射任何元素,而是获得了仅包含信息的XML表示形式。
更新资料
发布上一个示例后,我意识到它实际上按预期工作,这使我更加困惑。尽管我试图在生产代码中复制(以前的)工作示例没有成功,但是尽管我设法将示例中遇到的问题实际引入了。由于我需要添加一个名称空间来解决问题,因此我假设它与命名约定和X(ml)Path有关。
我还添加package- info.java
了使用这些对象时正在使用的编组器/解组器。由于jaxb.properties不包含任何令人兴奋的内容,因此省略了它。
当我运行您的示例时,一切正常。由于您的实际模型可能具有get /
set方法,因此您需要确保将其添加@XmlAccessorType(XmlAccessType.FIELD)
到类中,否则MOXy(或任何其他JAXB
impl)还将相应的属性视为已映射(请参见: http://blog.bdoughan)。 com / 2011/06 / using-jaxbs-
xmlaccessortype-to.html)。
import java.util.List;
import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.XmlPath;
@XmlRootElement(name = "root")
@XmlAccessorType(XmlAccessType.FIELD)
public class Root {
@XmlPath("resource/information/date/text()")
private String date;
@XmlPath("resource/information/name/text()")
private String name;
@XmlPath("resource/elements/element")
private List<Element> elements;
}
您还需要确保具有jaxb.properties
与域模型相同的文件包,并带有以下条目,以将MOXy指定为JAXB提供程序(请参阅:http ://blog.bdoughan.com/2011/05/specifying-
eclipselink- moxy-as-your.html)。
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
想要查询更多的信息
更新#1
当您的文档经过名称空间限定时,@XmlPath
注释需要考虑在内。可以根据@XmlSchema
注释限定路径中的节点。
包装信息
在您的package-info
类中,前缀s
被分配给名称空间URI http://www.example.eu/test
。
@XmlSchema(
namespace = "http://www.example.eu/test",
attributeFormDefault = XmlNsForm.QUALIFIED,
elementFormDefault = XmlNsForm.QUALIFIED,
xmlns = {
@XmlNs(
prefix = "s",
namespaceURI = "http://www.example.eu/test")
},
location = "http://www.example.eu/test ResourceSchema.xsd")
package se.example.mavenproject1;
import javax.xml.bind.annotation.XmlNs;
import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;
根
这意味着符合http://www.example.eu/test
名称空间的节点应s
在@XmlPath
注释中具有前缀。
import java.util.List;
import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.XmlPath;
@XmlRootElement(name = "root")
@XmlAccessorType(XmlAccessType.FIELD)
public class Root {
@XmlPath("s:resource/s:information/s:date/text()")
private String date;
@XmlPath("s:resource/s:information/s:name/text()")
private String name;
@XmlPath("s:resource/s:elements/s:element")
private List<Element> elements;
}
更新#2
因此,似乎在将路径映射到复杂对象时,需要在@XmlPath中指定名称空间,但是在将路径映射到简单对象(如String或整数)时可以跳过命名空间。
这是一个错误。您应该@XmlPath
像处理复杂对象一样,对命名空间限定简单对象的权限(请参阅UPDATE#1)。正确的映射今天有效,我们将修复以下错误,以便正确的映射行为正确。您可以使用下面的链接跟踪我们在此问题上的进展:
我有一个很深的XML结构,它有很多无意义的包装器,我要映射到一个Java类。用@xmlpath映射简单的数据类型是一种尝试,但当涉及到实际上需要自己的类的类型时,我不太确定该如何做,特别是当这些类型也应该放在列表中时。 XML结构示例 root.java RefObj.java 更新 在发布了前面的示例之后,我意识到它实际上是按照预期工作的,这让我更加困惑。尽管我试图在生产代码中复制(以前的)工作
我不明白为什么我在下面所做的XmlPath映射会显示为NULL。我的语法有问题吗?我在别处使用了类似的语法,没有问题。 谢谢你提供的线索..约翰
即使在尝试了许多事情之后也无法找到解决方案,因此在此处发布希望获得一些解决此问题或修复方法。 基本上,如果 ,但是除了< code>Map之外,我还需要一个< code>@XmlElement。因此有一个字段用< code >(映射字段)@XmlPath(" .)和另一个带有< code>@XmlElement的字符串字段,然后我想执行< code >解组。 以下是我尝试 : 下面是它将被< co
我正在尝试使用MOXY的XML元数据扩展映射下面的接口。但当我尝试加载它时,我得到以下错误。我不能将公共构造函数添加到中,因为它是枚举。 我的问题是:为什么Moxy impl在xml元数据中没有指定?
有人能帮助我使用EclipseLink MOXY使用JAXB编组生成带有重复标记的XML吗。 使用下面的方法,我将从带注释的bean生成XML。 多谢你
我正在使用Jersey Web services(2.23),并将POJO映射用于JSON到对象的映射(Jersey-media-moxy)。我创建了一个类,如下所示: 我希望该对象的实例具有以下结构: