首页 > 解决方案 > 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 作为值的映射中。我有点卡在这里。

标签: javaxml-parsing

解决方案


在我的例子中,我使用 XPath 解析 XML 文件,您可以获取属性名称和值,如该线程中所示: XPath getting attribute


推荐阅读