java - Java 解析 XML 并映射到对象
问题描述
我有一个需要用 POJO 映射的 XML 文件。我的 XML 看起来像这样:
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<contentType>Document</contentType>
<siteName>mySite</siteName>
<listName>myLib</listName>
<folderName>docset-folder</folderName>
<documentSetName>documentSet</documentSetName>
<fields>
<field name="META_1">123456789</field>
<field name="META_2">Someone</field>
<field name="META_3">Germany</field>
</fields>
</data>
我的 POJO 看起来像这样:
public class MetaData implements Serializable {
private String contentType;
private String siteName;
private String listName;
private String folderName;
private String documentSetName;
private Map<String, Object> fields;
}
我的目标是能够将任何 XML 与任何 POJO 映射,为此我找到了如何列出类的成员。在这个阶段,我有一个允许迭代节点列表的方法。
public static Iterable<Node> iterable(final NodeList nodeList) {
return () -> new Iterator<Node>() {
private int index = 0;
@Override
public boolean hasNext() {
return index < nodeList.getLength();
}
@Override
public Node next() {
if (!hasNext())
throw new NoSuchElementException();
return nodeList.item(index++);
}
};
}
还有一个我尝试使用 DocumentBuilderFactory 的主要方法:
public static void main(String[] args) throws IOException, SAXException, ParserConfigurationException {
String path = "src/test/resources/bill.xml";
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// list the members of the metadata class
List<Field> fields = Arrays.asList(MetaData.class.getDeclaredFields());
try {
dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new File(path));
doc.getDocumentElement().normalize();
System.out.println("Root Element :" + doc.getDocumentElement().getNodeName());
System.out.println("------");
NodeList list = doc.getElementsByTagName("data");
iterable(list).forEach(node -> {
if (node.getNodeType() == Node.ELEMENT_NODE) {
Element element = (Element) node;
fields.forEach(field -> {
if(element.getAttribute(field.getName()).length() > 0) {
System.out.println(element.getAttribute(field.getName()));
} else {
System.out.print(element.getElementsByTagName(field.getName()).item(0).getNodeName());
System.out.println(" - " + element.getElementsByTagName(field.getName()).item(0).getTextContent());
}
});
}
// System.out.println(node.getTextContent());
});
} catch (ParserConfigurationException | SAXException | IOException e) {
e.printStackTrace();
}
}
我在这里只是测试获取 XML 属性、属性和值。这段代码给了我以下结果:
contentType - Document
siteName - mySite
listName - myLib
folderName - docset-folder
documentSetName - documentSet
fields -
123456789
Someone
Germany
我的问题是:我期望以下内容:
contentType - Document
siteName - mySite
listName - myLib
folderName - docset-folder
documentSetName - documentSet
fields -
META_1 - 123456789
META_2 - Someone
META_3 - Germany
我的目标是能够将它与 MetaData 对象映射。此处的字段应添加到以 META_1 作为键和 123456789 作为值的映射中。我有点卡在这里。
解决方案
在我的例子中,我使用 XPath 解析 XML 文件,您可以获取属性名称和值,如该线程中所示: XPath getting attribute
推荐阅读
- docker - 尝试连接到 unix:///var/run/docker.sock 的 Docker 守护进程套接字时权限被拒绝
- c++ - 为什么缩小转换不能防止这个不正确类型的 map.insert() 失败?
- sql-server - 基于可选数据的过滤
- linux - 在用户使用 GNOME 登录之前启动应用程序
- python - 19.0.1 更新后使用 pip 命令出错
- ios - 如果您的应用程序播放视频并暂停背景音频,您如何在完成后让背景音频恢复?
- javascript - 将内容添加到动态创建的表格的单个单元格
- azure - 天蓝色事件网格中的订阅验证事件消息架构是什么?
- c# - 动态调度 - C# 中的模板方法
- javascript - 在 webpack 项目中有单独的 js 对象,它们与相同的变量交互