获取多个具有相同名称 JAXB 的 XML 元素
Getting multiple XML elements with the same name JAXB
可能是个愚蠢的问题,但我被卡住了。
我尝试解析从 REST service 检索到的巨大 xml 文档。
我感兴趣的是两个抽象部分。
<article article-type="research-article">
<front>
<article-meta>
<abstract></abstract>
<abstract abstract-type="summary"></abstract>
</article-meta>
</front>
</article>
在我面前class,我做了以下事情:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement
public class Front {
@XmlElementWrapper(name = "article-meta")
@XmlElement(name="abstract")
private List<AuthorSummary> authorSummaries = new ArrayList<AuthorSummary>();
/** Getter and Setter **/
}
遗憾的是,我只得到了第一个摘要,但还有内容。你可以在下面看到我的 AuthorSummary Class。
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement
public class AuthorSummary {
@XmlElement(name = "title")
private String title;
@XmlElement(name = "p")
private String content;
@XmlAttribute(name = "abstract-type")
private String abstractType;
/** Getter and Setter **/
}
所以,我被卡住了,很高兴得到任何提示。
非常感谢
我有一个解决方案,但它根本没有使用 jaxb 甚至数据绑定。因此,如果您坚持使用数据绑定,我将删除我的答案。否则,我喜欢你指向 data projection(披露:我隶属于该项目)而不是数据绑定:
public class ReadElementsWithSameName {
public interface Article {
@XBRead("./@article-type")
String getType();
@XBRead("./front/article-meta/abstract")
List<String> getAllAbstracts();
@XBRead("./front/article-meta/abstract[@abstract-type='summary']")
String getSummary();
}
// Configure the underlying document builder to not load the (nonexisting) DTD
private static final XMLFactoriesConfig nonValidatingConfig = new DefaultXMLFactoriesConfig() {
@Override
public DocumentBuilderFactory createDocumentBuilderFactory() {
DocumentBuilderFactory factory = super.createDocumentBuilderFactory();
try {
factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
} catch (ParserConfigurationException e) {
throw new RuntimeException(e);
}
return factory;
}
};
public static void main(String... args) throws IOException {
List<Article> articles = new XBProjector(nonValidatingConfig).io().url("res://data.xml").evalXPath("/article").asListOf(Article.class);
for (Article article:articles) {
System.out.println(article.getType());
System.out.println(article.getSummary());
System.out.println(article.getAllAbstracts());
}
}
}
不是用 java 类 反映 XML 结构,而是将 Java API 定义为 "projection interface" 和访问器(和二传手)你喜欢拥有。之后,让投影框架负责读取和写入对 DOM.
的更改
可能是个愚蠢的问题,但我被卡住了。
我尝试解析从 REST service 检索到的巨大 xml 文档。 我感兴趣的是两个抽象部分。
<article article-type="research-article">
<front>
<article-meta>
<abstract></abstract>
<abstract abstract-type="summary"></abstract>
</article-meta>
</front>
</article>
在我面前class,我做了以下事情:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement
public class Front {
@XmlElementWrapper(name = "article-meta")
@XmlElement(name="abstract")
private List<AuthorSummary> authorSummaries = new ArrayList<AuthorSummary>();
/** Getter and Setter **/
}
遗憾的是,我只得到了第一个摘要,但还有内容。你可以在下面看到我的 AuthorSummary Class。
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement
public class AuthorSummary {
@XmlElement(name = "title")
private String title;
@XmlElement(name = "p")
private String content;
@XmlAttribute(name = "abstract-type")
private String abstractType;
/** Getter and Setter **/
}
所以,我被卡住了,很高兴得到任何提示。
非常感谢
我有一个解决方案,但它根本没有使用 jaxb 甚至数据绑定。因此,如果您坚持使用数据绑定,我将删除我的答案。否则,我喜欢你指向 data projection(披露:我隶属于该项目)而不是数据绑定:
public class ReadElementsWithSameName {
public interface Article {
@XBRead("./@article-type")
String getType();
@XBRead("./front/article-meta/abstract")
List<String> getAllAbstracts();
@XBRead("./front/article-meta/abstract[@abstract-type='summary']")
String getSummary();
}
// Configure the underlying document builder to not load the (nonexisting) DTD
private static final XMLFactoriesConfig nonValidatingConfig = new DefaultXMLFactoriesConfig() {
@Override
public DocumentBuilderFactory createDocumentBuilderFactory() {
DocumentBuilderFactory factory = super.createDocumentBuilderFactory();
try {
factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
} catch (ParserConfigurationException e) {
throw new RuntimeException(e);
}
return factory;
}
};
public static void main(String... args) throws IOException {
List<Article> articles = new XBProjector(nonValidatingConfig).io().url("res://data.xml").evalXPath("/article").asListOf(Article.class);
for (Article article:articles) {
System.out.println(article.getType());
System.out.println(article.getSummary());
System.out.println(article.getAllAbstracts());
}
}
}
不是用 java 类 反映 XML 结构,而是将 Java API 定义为 "projection interface" 和访问器(和二传手)你喜欢拥有。之后,让投影框架负责读取和写入对 DOM.
的更改