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 个新问题!
我意识到我可能需要所有记录的地图列表。
- 我设法使用上面的 Table class 获取了最后一条记录的键和值。如何将它变成一个地图列表,以便我可以获取每条记录,而不仅仅是最后一条?
- 另一个问题是 Table class 只有在我的 xml 中没有 RECORDS 标签时才有效。我该如何解决?
您需要能够使用您提供的 中的 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}]
如您所见,解析后的数据具有所有值,并且与原始数据匹配。
所以我有几个 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 个新问题! 我意识到我可能需要所有记录的地图列表。
- 我设法使用上面的 Table class 获取了最后一条记录的键和值。如何将它变成一个地图列表,以便我可以获取每条记录,而不仅仅是最后一条?
- 另一个问题是 Table class 只有在我的 xml 中没有 RECORDS 标签时才有效。我该如何解决?
您需要能够使用您提供的 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}]
如您所见,解析后的数据具有所有值,并且与原始数据匹配。