JAXB XML 动态解组

JAXB XML Dynamic Unmarshalling

所以我有几个 XML 正在尝试解组。

一个 XML 可以是这样的:

<TABLE>
    <RECORDS>
        <RECORD>
            <DOC_ID>some value</DOC_ID>
            <ENTITY_ID>some value</ENTITY_ID>
            ...more entries
        </RECORD>
        <RECORD>
            <DOC_ID>some value</DOC_ID>
            <ENTITY_ID>some value</ENTITY_ID>
            ...more entries
        </RECORD>
    </RECORDS>
</TABLE>

另一个XML也可以是这样的:

<TABLE>
    <RECORDS>
        <RECORD>
            <SUB_ID>some value</SUB_ID>
            <CASE_DOC_ID>some value</CASE_DOC_ID>
            ...more entries
        </RECORD>
        <RECORD>
            <SUB_ID>some value</SUB_ID>
            <CASE_DOC_ID>some value</CASE_DOC_ID>
            ...more entries
        </RECORD>
    </RECORDS>
</TABLE>

每个 XML 始终将 TABLE 作为根,将 RECORDS 作为 child,并将 RECORD 作为 grandchild,只是 RECORD 中的数据不同。

我不想编组任何东西,只是解组并获取数据。

在我的TableClass里面我有

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "TABLE")
public class Table {

    @XmlJavaTypeAdapter(MapAdapter.class)
    private Map<String, String> RECORDS;

    public Map<String, String> getMap() {
        return RECORDS;
    }

    public void setMap(Map<String, String> record) {
        this.RECORDS = record;
    }

}

我从这个 link 中获取了 MapAdapter:

我的问题是: 我希望能够获取记录中的每个标签名称(DOC_ID/SUB_ID 或 XML 中的任何内容),当我传入 XML 时,它的每个值都作为字符串,但我'我不知道该怎么做。

如能为我指明正确的方向,我们将不胜感激。

编辑:

2 个新问题! 我意识到我可能需要所有记录的地图列表。

您需要能够使用您提供的 中的 MapAdapter 注释 Map,因此您需要创建一个子 class。

@XmlJavaTypeAdapter(MapAdapter.class)
public class Record extends HashMap<String, String> {
}

那么你的 Table class 就足够简单了,尽管你需要用 @XmlElementWrapper 注释才能获得 XML.

的额外级别
@XmlRootElement(name = "TABLE")
public class Table {
    private List<Record> records = new ArrayList<>();

    @XmlElementWrapper(name = "RECORDS")
    @XmlElement(name = "RECORD")
    public List<Record> getRecords() {
        return this.records;
    }
    public void setRecords(List<Record> records) {
        this.records = records;
    }
}

当使用 JAXB 并且解析没有加载所有信息时,我发现先将代码编写为 generate XML 会有所帮助,因为然后,您可以在生成的 XML 中看到 JAXB 映射与您的 expected/intended.

有何不同

如果您在上述 classes 中添加一些辅助方法,则创建示例数据会更容易,所以让我们先这样做:

@XmlJavaTypeAdapter(MapAdapter.class)
public class Record extends HashMap<String, String> {
    private static final long serialVersionUID = 1L;

    public Record addElement(String name, String value) {
        put(name, value);
        return this;
    }

    @Override
    public String toString() {
        return "Record" + super.toString();
    }
}
@XmlRootElement(name = "TABLE")
public class Table {
    private List<Record> records;

    public Table() {
        this.records = new ArrayList<>();
    }
    public Table(Record... records) {
        this.records = Arrays.asList(records);
    }

    @XmlElementWrapper(name = "RECORDS")
    @XmlElement(name = "RECORD")
    public List<Record> getRecords() {
        return this.records;
    }
    public void setRecords(List<Record> records) {
        this.records = records;
    }

    @Override
    public String toString() {
        return "Table" + this.records.toString();
    }
}

然后我们可以轻松编写测试代码,看看是否一切正常。

构建数据生成为XML

Table table1 = new Table(
        new Record().addElement("DOC_ID", "some value")
                    .addElement("ENTITY_ID", "some value"),
        new Record().addElement("SUB_ID", "some value")
                    .addElement("CASE_DOC_ID", "some value")
);
System.out.println(table1);
Table[Record{DOC_ID=some value, ENTITY_ID=some value}, Record{SUB_ID=some value, CASE_DOC_ID=some value}]

生成XML

String xml;
try (StringWriter out = new StringWriter()) {
    JAXBContext jaxbContext = JAXBContext.newInstance(Table.class);
    Marshaller marshaller = jaxbContext.createMarshaller();
    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
    marshaller.marshal(table1, out);
    xml = out.toString();
}
System.out.println(xml);
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<TABLE>
    <RECORDS>
        <RECORD>
            <DOC_ID>some value</DOC_ID>
            <ENTITY_ID>some value</ENTITY_ID>
        </RECORD>
        <RECORD>
            <SUB_ID>some value</SUB_ID>
            <CASE_DOC_ID>some value</CASE_DOC_ID>
        </RECORD>
    </RECORDS>
</TABLE>

我们可以确认 JAXB 映射生成了我们打算解析的 XML 格式。

解析XML

Table table2;
{
    JAXBContext jaxbContext = JAXBContext.newInstance(Table.class);
    Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
    table2 = (Table) unmarshaller.unmarshal(new StringReader(xml));
}
System.out.println(table2);
Table[{DOC_ID=some value, ENTITY_ID=some value}, {SUB_ID=some value, CASE_DOC_ID=some value}]

如您所见,解析后的数据具有所有值,并且与原始数据匹配。