将单个 xml 节点转换为 java class

Convert single xml node into java class

我有一个 XML 文件,我不知道它的一般架构。 在此 XML 中,我试图解析 table 我确实知道其架构的元素;它们采用标准 html 表格格式。

我忽略所有使用 this answer 的 dtd 引用并像这样提取我的 table 节点:

    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    dbf.setValidating(false);
    dbf.setNamespaceAware(true);
    dbf.setFeature("http://xml.org/sax/features/namespaces", false);
    dbf.setFeature("http://xml.org/sax/features/validation", false);
    dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false);
    dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
    DocumentBuilder db = dbf.newDocumentBuilder();
    Document doc = db.parse(input);
    NodeList tables = doc.getElementsByTagName("table");

假设我有一个域 class 用于 table,是否有一种简单的方法可以将这些节点映射到 java 对象?

首先,如果您碰巧要解析 HTML,您确实需要使用 HTML 解析器,因为 XML 解析器将无法解析它。也就是说,通过一些编码,您可以使用 SimpleXml 完成此操作。

步骤如下:

  1. 创建解析器实例(无需配置,DTD 和名称空间被故意排除在解析器之外)
  2. 将 XML 解析为 DOM 树
  3. 使用 getElementsByTagName("table") 获取所有 table 元素
  4. 遍历列表并将 DOM 个元素转换为 POJO

事实证明,SimpleXml 没有开箱即用的 getElementsByTagName(),所以我写了一个。这是完整的代码:

import xmlparser.XmlParser;
import xmlparser.annotations.XmlName;
import xmlparser.annotations.XmlTextNode;
import xmlparser.model.XmlElement;

import java.util.ArrayList;
import java.util.List;

public final class Question {

    private static final String xml =
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
        "<!DOCTYPE note SYSTEM \"Note.dtd\">\n" +
        "<note>\n" +
            "<to>Tove</to>\n" +
            "<from>Jani</from>\n" +
            "<heading>Reminder</heading>\n" +
            "<body>Don't forget me this weekend!</body>\n" +
            "<sometag>\n" +
                "<table>\n" +
                    "<tr><td>content</td></tr>\n" +
                "</table>\n" +
            "</sometag>\n" +
        "</note>\n";

    @XmlName("table")
    private static class Table {
        private List<Question.Row> tr;
    }
    private static class Row {
        private List<Cell> td;
    }
    private static class Cell {
        @XmlTextNode
        private String text;
    }

    public static void main(final String... args) {
        final XmlParser simple = new XmlParser();
        final XmlElement xmlElement = simple.fromXml(xml);
        final List<XmlElement> list = getElementsByTagName(xmlElement, "table");
        for (final XmlElement element : list) {
            Table table = simple.fromXml(element, Table.class);
            System.out.println(table.tr.get(0).td.get(0).text);
        }
    }

    private static List<XmlElement> getElementsByTagName(final XmlElement element, final String name) {
        final List<XmlElement> list = new ArrayList<>();
        getElementsByTagName(element, name, list);
        return list;
    }
    private static void getElementsByTagName(final XmlElement element, final String name, final List<XmlElement> list) {
        if (element == null) return;
        if (name.equals(element.name)) list.add(element);
        if (element.children == null) return;
        for (final XmlElement child : element.children) {
            getElementsByTagName(child, name, list);
        }
    }

}

代码的输出将是包含单词 'content' 的单行。

SimpleXml 在 Maven 中心:https://mvnrepository.com/artifact/com.github.codemonstur/simplexml/2.8.1