如何使用JAXB解组根元素集合?

时间:2012-10-10 15:10:38

标签: xml serialization collections jaxb

从某个库,我得到这样一个输入字符串:

<link>
    <name>button1</name>
    <target>there</target>
</link>
<link>
    <name>button2</name>
    <target>there2</target>
</link>

(请注意,这不是XML文档,因为它没有root)并且我有这个类:

@XmlRootElement(name = "link")
public class TableTagLinkElement {
    private String name;
    private String target;

    // getters and setters
}

如何以一般方式轻松地将其解组为TableTagLinkElement s 列表,以便我可以实施此方法:

public <T> List<T> parseCollection(String xmlString, Class<T> rootClass)

即,之前没有TableTagLinkElement类或<link>标签名称的任何知识?

我知道create a wrapper class with a list的解决方案,但我认为它们不适用于此,是吗?

1 个答案:

答案 0 :(得分:2)

如果你可以在完整的XML字符串周围包含一个<root>...</root>元素,那么你可以从该字符串创建一个XMLStreamReader读取,然后遍历读者,解组每个link作为你走。例如(省略异常处理)

public <T> List<T> parseCollection(String xmlString, Class<T> rootClass) {
  XMLInputFactory inFac = XMLInputFactory.newFactory();
  XMLStreamReader reader = inFac.createXMLStreamReader(
                    new StringReader("<root>" + xmlString + "</root>"));
  reader.nextTag(); // move to the <root> tag
  reader.nextTag(); // move to the first child
  List<T> list = new ArrayList<T>();
  while(reader.getEventType() == XMLStreamConstants.START_ELEMENT) {
    list.add(declaredType.cast(unmarshaller.unmarshal(reader)));

    // unmarshal leaves the reader pointing at the event *after* the
    // closing tag, not the END_ELEMENT event itself, so we can't just
    // do nextTag unconditionally.  We may already be on the next opening
    // tag or the closing </root> but we might need to advance if there
    // is whitespace between tags
    if(reader.getEventType() != XMLStreamConstants.START_ELEMENT &&
       reader.getEventType() != XMLStreamConstants.END_ELEMENT) {
      reader.nextTag();
    }
  }
  reader.close();
  return list;
}