JAXB Unmarshalling:对象列表

我有

@XmlRootElement(namespace = "http://www.w3.org/2005/Atom", name = "content") @XmlType(name = "course") public class Course implements Resource ... @XmlElementWrapper(name="subcourses") @XmlElement(name="course") List subcourses; //!? 

和Xlink类,它在内联变量中工作正常。

 public class Xlink { private String href; private String value; @XmlAttribute(namespace = "http://www.w3.org/1999/xlink") public String getHref() { return href; } public void setHref(String href) { this.href = href; } @XmlValue public String getValue() { return value; } public void setValue(String value) { this.value = value; } } 

用于XML输入

  ...  Some course other course 

子主义拒绝被解组(没有任何exception被抛出)。

注意:遗憾的是MOXy不是一个选项。

编辑:新的编组对象

   SOME CODE name  some value sdfhdfhdhdh   

Edit2:在对一个测试对象进行解组和编组的一些实验后,我发现我需要在内容的头部定义xmlns命名空间以匹配xlink:href= like xmlns:xlink="http://www.w3.org/1999/xlink"问题是我从一个由resteasy解析出来的包装类中获取了Course元素。 因此,结果类不会遗留名称空间信息。

我不知何故需要强迫JAXB理解xmlns:xlink="http://www.w3.org/1999/xlink"适用于课程元素,但经过一个小时的google后我感到很茫然。

编辑3:我从我的对象

https://github.com/jirutka/atom-jaxb/blob/master/src/main/java/cz/jirutka/atom/jaxb/Entry.java

这是在服务器对应物上使用的。 这反过来又是其中的一部分

https://github.com/jirutka/atom-jaxb/blob/master/src/main/java/cz/jirutka/atom/jaxb/Feed.java

我的解组代码的相关部分是:

 Feed f = r.readEntity(Feed.class); out.addAll(unmarshaller.Unmarshal(f.getEntries(), clazz)); 

其中rjavax.ws.rs.core.Response 。 和unmarshaller

 public List Unmarshal(List entries, Class clazz) { List out = new ArrayList(); T instance; for (Entry e : entries) { try { JAXBContext context = JAXBContext.newInstance(clazz); Unmarshaller unmarsh = context.createUnmarshaller(); instance = (T) unmarsh.unmarshal((Node) e.getContent()); 

由于这是我第一次使用这项技术,这个代码完全有可能是’wtf’。

当您注释该字段(实例变量)时,请确保在您的类上放置@XmlAccessorType(XmlAccessType.FIELD)

 import java.util.List; import javax.xml.bind.annotation.*; @XmlRootElement(namespace = "http://www.w3.org/2005/Atom", name = "content") @XmlAccessorType(XmlAccessType.FIELD) public class Course implements Resource { @XmlElementWrapper(name = "subcourses") @XmlElement(name = "course") List subcourses; } 

然后确保您的XML输入正确地进行了命名空间限定。 您的输入文档应如下所示:

   SOME CODE name  some value sdfhdfhdhdh   

通过我更新的Course类,您的Xlink类和正确的命名空间限定的XML文档,以下演示代码对我来说非常有效。

 import java.io.File; import javax.xml.bind.*; public class Demo { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(Course.class); Unmarshaller unmarshaller = jc.createUnmarshaller(); File xml = new File("src/forum17766166/input.xml"); Course course = (Course) unmarshaller.unmarshal(xml); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.marshal(course, System.out); } } 

更新#1

Edit2:在对一个测试对象进行解组和编组的一些实验后,我发现我需要在内容的头部定义xmlns命名空间以匹配xlink:href = like xmlns:xlink =“http://www.w3.org/ 1999 / xlink“问题是我从一个由resteasy解析出来的包装类中获取了Course元素。 因此,结果类不会遗留名称空间信息。

解决问题的最佳位置是提取您想要解组的片段。 以下是您可以使用StAX的策略。

input.xml中

下面是一个示例XML文档,其中命名空间信息定义在您要解组的片段上方。

     SOME CODE name  some value sdfhdfhdhdh     

演示

下面我们将使用StAX XMLStreamReader导航到目标片段。 我们将让我们的JAXB实现解组这个片段。 这样就可以保留所有命名空间信息。

 import javax.xml.bind.*; import javax.xml.stream.*; import javax.xml.transform.stream.StreamSource; public class Demo { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(Course.class); XMLInputFactory xif = XMLInputFactory.newFactory(); StreamSource source = new StreamSource("src/forum17766166/input.xml"); XMLStreamReader xsr = xif.createXMLStreamReader(source); while(xsr.hasNext()) { if(xsr.isStartElement() && "content".equals(xsr.getLocalName())) { break; } xsr.next(); } Unmarshaller unmarshaller = jc.createUnmarshaller(); Course course = (Course) unmarshaller.unmarshal(xsr); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.marshal(course, System.out); } } 

产量

    some value sdfhdfhdhdh   

更新#2

如果您无法按照UPDATE#1中的描述生成更好的XML片段,下面就是如何修复当前的XML片段。

NamespaceFilter

您可以使用SAX XMLFilter来修复XML文档。

 import org.xml.sax.*; import org.xml.sax.helpers.*; public class NamespaceFilter extends XMLFilterImpl { private static final String ATOM_URI = "http://www.w3.org/2005/Atom"; private static final String XLINK_URI = "http://www.w3.org/1999/xlink"; @Override public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException { if("atom:content".equals(qName)) { super.startElement(ATOM_URI, "content", qName, atts); } else if("course".equals(qName)) { AttributesImpl modifiedAtts = new AttributesImpl(); modifiedAtts.addAttribute(XLINK_URI, "href", "xlink:href", null, atts.getValue(0)); super.startElement(uri, localName, qName, modifiedAtts); } else { super.startElement(uri, localName, qName, atts); } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { if("atom:content".equals(qName)) { super.endElement(ATOM_URI, "content", qName); } else { super.endElement(uri, localName, qName); } } } 

演示

下面是如何利用XmlFilter和JAXB:

 import javax.xml.bind.*; import javax.xml.parsers.*; import org.xml.sax.*; public class Demo { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(Course.class); // Create the XMLFilter XMLFilter filter = new NamespaceFilter(); // Set the parent XMLReader on the XMLFilter SAXParserFactory spf = SAXParserFactory.newInstance(); SAXParser sp = spf.newSAXParser(); XMLReader xr = sp.getXMLReader(); filter.setParent(xr); // Set UnmarshallerHandler as ContentHandler on XMLFilter Unmarshaller unmarshaller = jc.createUnmarshaller(); UnmarshallerHandler unmarshallerHandler = unmarshaller .getUnmarshallerHandler(); filter.setContentHandler(unmarshallerHandler); // Parse the XML InputSource xml = new InputSource("src/forum17766166/input.xml"); filter.parse(xml); Course course = (Course) unmarshallerHandler.getResult(); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.marshal(course, System.out); } } 

欲获得更多信息


更新#3

下面是示例代码的简化版本,其中一切正常。 也许你的代码中有一些不同的东西可以帮助你找到它们。

条目

 import javax.xml.bind.annotation.*; @XmlRootElement(namespace="http://www.w3.org/2005/Atom") @XmlAccessorType(XmlAccessType.FIELD) public class Entry { @XmlElement(namespace = "http://www.w3.org/2005/Atom") @XmlSchemaType(name = "atomInlineOtherContent") private T content; public T getContent() { return content; } } 

input.xml中

    SOME CODE name  some value sdfhdfhdhdh    

演示

 import java.io.File; import javax.xml.bind.*; import org.w3c.dom.Node; public class Demo { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(Entry.class, Course.class); // Unmarshal Entry Unmarshaller unmarshaller = jc.createUnmarshaller(); File xml = new File("src/forum17766166/input.xml"); Entry entry = (Entry) unmarshaller.unmarshal(xml); // Unmarshal Course Node contentNode = (Node) entry.getContent(); Course course = (Course) unmarshaller.unmarshal(contentNode); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.marshal(course, System.out); } } 

产量

    some value sdfhdfhdhdh