我目前正在使用XStream来解析XML文件,但无法让它做我需要它做的事情。如有必要,我将改为另一个图书馆,无论什么可以解决这个问题!
基本上我正在尝试解析类似于此的XML Feed:
<product>
<title>Transformers Best of Grimlock</title>
<author1>Bob Budiansky</author1>
<author2>Simon Furman</author2>
</product>
我正在尝试解析这样的模型:
public class Product extends Model {
public String title;
public List<String> authors;
}
标题很有效,但我在解析作者方面遇到了困难。不幸的是,以这种“更合理”的格式获取XML提要不是一种选择:
...
<authors>
<author>Bob Budiansky</author>
<author>Simon Furman</author>
</authors>
...
我可以做些什么来解析“author1”,“author2”等到列表中吗?
请记住我对XStream很新(并且根本没有使用JAXB!)因此,如果我要编写任何自定义绑定器或其他任何内容,需要指明从哪里开始。
感谢您的阅读,我期待任何可能拯救我理智的潜在解决方案! :)
修改:我已更新帖子以显示我没有与XStream绑定。真的很难找到答案 - 也许我只是不知道该搜索什么......
答案 0 :(得分:3)
以下方法适用于任何可以从StAX XMLStreamReader
解组的XML绑定库。我将在下面使用标准的JAXB(JSR-222)API进行演示。 (注意:我是EclipseLink JAXB (MOXy)领导者。
<强>产品强>
我们将注释模型,就像authors
属性映射到author
元素一样。
package forum11666565;
import java.util.List;
import javax.xml.bind.annotation.*;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Product extends Model {
public String title;
@XmlElement(name = "author")
public List<String> authors;
}
<强>演示强>
我们将使用XMLStreamReader
解析XML文档。在XMLStreamReader
上,我们将创建一个StreamReaderDelegate
,它会将以author
开头的所有元素报告为名为author
的元素。
package forum11666565;
import java.io.FileInputStream;
import javax.xml.bind.*;
import javax.xml.stream.*;
import javax.xml.stream.util.StreamReaderDelegate;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Product.class);
XMLInputFactory xif = XMLInputFactory.newFactory();
XMLStreamReader xsr = xif.createXMLStreamReader(new FileInputStream("src/forum11666565/input.xml"));
xsr = new StreamReaderDelegate(xsr) {
@Override
public String getLocalName() {
String localName = super.getLocalName();
if(localName.startsWith("author")) {
return "author";
} else {
return localName;
}
}
};
Unmarshaller unmarshaller = jc.createUnmarshaller();
Product product = (Product) unmarshaller.unmarshal(xsr);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(product, System.out);
}
}
<强> input.xml中强>
<product>
<title>Transformers: Best of Grimlock</title>
<author1>Bob Budiansky</author1>
<author2>Simon Furman</author2>
</product>
<强>输出强>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<product>
<title>Transformers: Best of Grimlock</title>
<author>Bob Budiansky</author>
<author>Simon Furman</author>
</product>
答案 1 :(得分:2)
在使用XStream解析初始XML之前,您可以通过XSLT转换初始XML:
XSLT样式表将根据需要转换XML:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="product">
<xsl:element name="product">
<xsl:for-each select="*[not(starts-with(name(.), 'author'))]">
<xsl:copy-of select="." />
</xsl:for-each>
<xsl:element name="authors">
<xsl:for-each select="*[starts-with(name(.), 'author')]">
<xsl:element name="author">
<xsl:value-of select="."/>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:element>
</xsl:template>
<xsl:template match="*">
<xsl:copy select=".">
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>