输入:
<?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>
包测试中的类:
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<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());
结果是,该文本在ContentRoot中设置,但在Content中没有(我从上一个System.out.println()获得NullPointerException)。有人可以告诉我为什么吗?
答案 0 :(得分:1)
有一些物品让你沮丧:
ContentRoot
包含无效映射 EclipseLink JAXB (MOXy)不允许以下映射组合。使用第二个xml-element
,您告诉MOXy将contents
属性映射到元素b
中出现的重复元素a
。使用第一个xml-element
,您尝试将可能多个b
元素之一的text属性映射到String
属性text
。
<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>
映射text
属性的正确位置位于您已拥有的Content
类上。我建议使用xml-element
映射并指定xml-path
。
name
(可行) >
<java-type name="Content">
<java-attributes>
<xml-attribute java-attribute="text"/>
</java-attributes>
</java-type>
xml-path
未正确命名空间因为在bindings.xml
中您已将foo
前缀与http://www.domain.org/foo
命名空间URI相关联。
<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>
指定xml-path
时,需要包含前缀才能获得正确的命名空间限定。
<java-type name="ContentRoot">
<java-attributes>
<xml-element java-attribute="contents" xml-path="foo:a/foo:b"/>
</java-attributes>
</java-type>
了解更多信息
或者,您可以使用xml-element-wrapper
映射它,如下所示:
<java-type name="ContentRoot">
<java-attributes>
<xml-element java-attribute="contents" name="b">
<xml-element-wrapper name="a"/>
</xml-element>
</java-attributes>
</java-type>
xml-path="."
不能用于集合属性目前,MOXy要求集合中的每个项目都对应于自己的元素。这意味着此时您无法为集合属性指定自我XPath .
。
您的演示代码似乎与您的域模型完全匹配。这是一个将所有内容整合在一起的完整示例:
<强>根强>
package test;
public class Root {
private ContentRoot contentRoot;
public ContentRoot getContentRoot() {
return contentRoot;
}
public void setContentRoot(ContentRoot contentRoot) {
this.contentRoot = contentRoot;
}
}
<强> ContentRoot 强>
package test;
import java.util.List;
public class ContentRoot {
private List<Content> contents;
public List<Content> getContents() {
return contents;
}
public void setContents(List<Content> contents) {
this.contents = contents;
}
}
内容强>
package test;
public class Content {
private String text;
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
<强> bindings.xml 强>
<?xml version="1.0"?>
<xml-bindings xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
package-name="test"
xml-accessor-type="FIELD">
<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/>
<java-attributes>
<xml-element java-attribute="contentRoot" xml-path="."/>
</java-attributes>
</java-type>
<java-type name="ContentRoot">
<java-attributes>
<xml-element java-attribute="contents" xml-path="foo:a/foo:b"/>
</java-attributes>
</java-type>
<java-type name="Content">
<java-attributes>
<xml-attribute java-attribute="text"/>
</java-attributes>
</java-type>
</java-types>
</xml-bindings>
<强>演示强>
package test;
import java.io.File;
import java.util.*;
import javax.xml.bind.*;
import org.eclipse.persistence.jaxb.JAXBContextFactory;
import org.eclipse.persistence.jaxb.JAXBContextProperties;
public class Demo {
public static void main(String[] args) throws Exception {
Map<String, Object> jaxbContextProperties = new HashMap<String, Object>(1);
jaxbContextProperties.put(JAXBContextProperties.OXM_METADATA_SOURCE, "test/bindings.xml");
JAXBContext jaxbContext = JAXBContextFactory.createContext(new Class[] {Root.class}, jaxbContextProperties);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
Root root = (Root)unmarshaller.unmarshal(new File("src/test/input.xml"));
System.out.println(root.getContentRoot().getContents().get(0).getText());
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(root, System.out);
}
}