3

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

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

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

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

    // getters and setters
}

我怎样才能以一种通用的方式轻松地将其解组为TableTagLinkElements列表,以便我可以实现这样的方法:

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

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

我知道使用 list 创建包装类的解决方案,但我认为它们不适用于这里,是吗?

4

1 回答 1

2

如果您可以<root>...</root>在完整的 XML 字符串周围包装一个元素,那么您可以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;
}
于 2012-10-10T15:49:01.783 回答