EclipseLink MOXy:绑定使用与不使用相同的XPath
输入:EclipseLink MOXy:绑定使用与不使用相同的XPath,xpath,binding,jaxb,eclipselink,moxy,Xpath,Binding,Jaxb,Eclipselink,Moxy,输入: 绑定: <?xml version="1.0" encoding="UTF-8"?> <foo:root xmlns:foo="http://www.domain.org/foo" xmlns="http://www.domain.org/foo" xmlns:xsd="http://www.w3.org/2001/XMLSchema#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-i
绑定:
<?xml version="1.0" encoding="UTF-8"?>
<foo:root xmlns:foo="http://www.domain.org/foo"
xmlns="http://www.domain.org/foo"
xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<a xsi:type="foo:someType">
<b text="some text" />
</a>
</foo:root>
包测试中的类:
<?xml version="1.0"?>
<xml-bindings
xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
package-name="test">
<xml-schema element-form-default="QUALIFIED" namespace="http://www.domain.org/foo">
<xml-ns prefix="foo" namespace-uri="http://www.domain.org/foo" />
</xml-schema>
<java-types>
<java-type name="Root">
<xml-root-element name="root"/>
<java-attributes>
<xml-element java-attribute="contentRoot" xml-path="." type="test.ContentRoot" />
</java-attributes>
</java-type>
<java-type name="ContentRoot">
<java-attributes>
<xml-element java-attribute="text" xml-path="a/b/@text" />
<xml-element java-attribute="contents" xml-path="a/b" type="test.Content" container-type="java.util.List" />
</java-attributes>
</java-type>
<java-type name="Content">
<java-attributes>
<xml-element java-attribute="text" xml-path="@text" />
</java-attributes>
</java-type>
</java-types>
</xml-bindings>
公共类根目录{
私有列表contentroot=newlinkedlist();
公共列表getContentRoots(){
返回contentroot;
}
public void setContentRoots(列出contentRoots){
this.contentRoots=contentRoots;
}
public void setContentRoot(ContentRoot ContentRoot){
this.contentRoot.add(contentRoot);
}
}
公共类ContentRoot{
私有列表内容;
私有字符串文本;
公共列表getContents(){
返回内容;
}
公共内容(列表内容){
this.contents=目录;
}
公共字符串getText(){
返回文本;
}
公共void setText(字符串文本){
this.text=文本;
}
}
公开课内容{
私有字符串文本;
公共字符串getText(){
返回文本;
}
公共void setText(字符串文本){
this.text=文本;
}
}
运行代码:
public class Root {
private List<ContentRoot> contentRoots = new LinkedList<ContentRoot>();
public List<ContentRoot> getContentRoots() {
return contentRoots;
}
public void setContentRoots(List<ContentRoot> contentRoots) {
this.contentRoots = contentRoots;
}
public void setContentRoot(ContentRoot contentRoot) {
this.contentRoots.add(contentRoot);
}
}
public class ContentRoot {
private List<Content> contents;
private String text;
public List<Content> getContents() {
return contents;
}
public void setContents(List<Content> contents) {
this.contents = contents;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
public class Content {
private String text;
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
Map jaxbContextProperties=newhashmap(1);
put(jaxbContextProperties.OXM_元数据_源,“bindings.xml”);
JAXBContext JAXBContext=JAXBContextFactory.createContext(新类[]{Root.Class},jaxbContextProperties);
Unmarshaller Unmarshaller=jaxbContext.createUnmarshaller();
Root=(Root)unmarshaller.unmarshal(新文件(“input.xml”);
System.out.println(root.getContentRoots().get(0.getText());
System.out.println(root.getContentRoots().get(0.getContents().get(0.getText());
结果是,文本在ContentRoot中设置,而不是在Content中设置(我从上一个System.out.println()中获得了一个NullPointerException)。有人能告诉我为什么吗?有几件事让你大吃一惊: 问题1-
ContentRoot
包含无效映射
不允许以下映射组合。对于第二个xml元素
,您告诉MOXy将内容
属性映射到元素a
中出现的重复元素b
。对于第一个xml元素
,您试图将可能存在的多个b
元素之一的文本属性映射到字符串
属性文本
映射text
属性的正确位置在您已经拥有的Content
类上。我将使用xml属性
映射并指定名称
,而不是使用xml元素
映射,使xml路径
指向属性(这会起作用)
Map<String, Object> jaxbContextProperties = new HashMap<String, Object>(1);
jaxbContextProperties.put(JAXBContextProperties.OXM_METADATA_SOURCE, "bindings.xml");
JAXBContext jaxbContext = JAXBContextFactory.createContext(new Class[] {Root.class}, jaxbContextProperties);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
Root root = (Root)unmarshaller.unmarshal(new File("input.xml"));
System.out.println(root.getContentRoots().get(0).getText());
System.out.println(root.getContentRoots().get(0).getContents().get(0).getText());
指定xml路径时
需要包含前缀以获得正确的命名空间限定
更多信息
xml元素包装器映射它,如下所示:
问题#3-xml path=“.”
不能用于集合属性
目前,MOXy要求集合中的每个项对应于它自己的元素。这意味着此时不能为集合属性指定自XPath
完整示例
您的演示代码似乎与您的域模型不完全匹配。下面是一个完整的示例,它将所有内容结合在一起:
根目录
封装测试;
公共类根{
私有ContentRoot ContentRoot;
公共ContentRoot getContentRoot(){
返回contentRoot;
}
public void setContentRoot(ContentRoot ContentRoot){
this.contentRoot=contentRoot;
}
}
ContentRoot
封装测试;
导入java.util.List;
公共类ContentRoot{
私有列表内容;
公共列表getContents(){
返回内容;
}
公共内容(列表内容){
this.contents=目录;
}
}
内容
封装测试;
公开课内容{
私有字符串文本;
公共字符串getText(){
返回文本;
}
公共void setText(字符串文本){
this.text=文本;
}
}
bindings.xml
演示
封装测试;
导入java.io.File;
导入java.util.*;
导入javax.xml.bind.*;
导入org.eclipse.persistence.jaxb.JAXBContextFactory;
导入org.eclipse.persistence.jaxb.JAXBContextProperties;
公开课演示{
公共静态void main(字符串[]args)引发异常{
Map jaxbContextProperties=newhashmap(1);
put(jaxbContextProperties.OXM_METADATA_源代码,“test/bindings.xml”);
JAXBContext JAXBContext=JAXBContextFactory.createContext(新类[]{Root.Class},jaxbContextProperties);
Unmarshaller Unmarshaller=jaxbContext.createUnmarshaller();
Root=(Root)unmarshaller.unmarshal(新文件(“src/test/input.xml”);
System.out.println(root.getContentRoot().getContents().get(0.getText());
Marshaller=jaxbContext.createMarshaller();
setProperty(marshaller.JAXB_格式化的_输出,true);
marshaller.marshall(root,System.out);
}
}
有几件事让你大吃一惊:
问题1-ContentRoot
包含无效映射
不允许以下映射组合。对于第二个xml元素
,您告诉MOXy将内容
属性映射到
<java-type name="Content">
<java-attributes>
<xml-attribute java-attribute="text"/>
</java-attributes>
</java-type>