简体   繁体   English

JAXB XML 动态解组

[英]JAXB XML Dynamic Unmarshalling

So I have a couple of XMLs which I'm trying to unmarshal.所以我有几个要解组的 XML。

One XML can look like this:一个 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>

Another XML can also look like this:另一个 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>

Each XML always has TABLE as root and RECORDS as a child and RECORD as grandchild just that the data in RECORD is different.每个 XML 始终将 TABLE 作为根,将 RECORDS 作为子项,将 RECORD 作为孙子项,只是 RECORD 中的数据不同。

I don't want to marshal anything, just unmarshal and get the data.我不想编组任何东西,只是解组并获取数据。

Inside my Table Class I have在我的表 Class 里面我有

@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;
    }

} }

I took MapAdapter from this link: JAXB Marshal and Unmarshal Map to/from <key>value</key>我从这个链接中获取了 MapAdapter: JAXB Marshal and Unmarshal Map to/from <key>value</key>

My issue is this: I would like to be able to get each Tag name in the record (DOC_ID/SUB_ID or whatever in the XML) and each of it's values as Strings when I pass in the XML but I'm not sure how to go about it.我的问题是:当我传入 XML 但我不知道如何go 关于它。

Any help to point me in the right direction would be appreciated.任何帮助我指出正确方向的帮助将不胜感激。

EDIT:编辑:

2 new questions. 2个新问题。 I realized I would probably need a list of Maps for all the records.我意识到我可能需要所有记录的地图列表。

  • I managed to get the last record's keys and values using the Table class above.我设法使用上面的表 class 获取最后一条记录的键和值。 How do I turn it into a list of Maps so I can get each record instead of just the last?如何将其转换为地图列表,以便我可以获取每条记录而不是最后一条?
  • Another question is the Table class only works if I don't have a RECORDS tag in my xml.另一个问题是表 class 只有在我的 xml 中没有 RECORDS 标签时才有效。 How do I fix that?我该如何解决?

You need to be able to annotate the Map with the MapAdapter from the link you provided, so you need to create a subclass.您需要能够使用您提供的链接中的MapAdapter注释Map ,因此您需要创建一个子类。

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

Then your Table class is simple enough, though you need to annotate with @XmlElementWrapper to get the extra level of XML.那么您的表 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;
    }
}

When working with JAXB and the parsing doesn't load all the information, I've found that it helps to first write code to generate XML, because you can then see, in the generated XML, how the JAXB mappings differ from what you expected/intended. When working with JAXB and the parsing doesn't load all the information, I've found that it helps to first write code to generate XML, because you can then see, in the generated XML, how the JAXB mappings differ from what you expected /故意的。

It's easier to create sample data if you add a few helper methods to the above classes, so lets do that first:如果向上述类添加一些辅助方法,则创建示例数据会更容易,所以让我们先这样做:

@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();
    }
}

Then we can easily write test code to see that it all works ok.然后我们可以很容易地编写测试代码,看看一切正常。

Build data to generate as XML构建数据以生成为 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}]

Generate XML生成 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>

We can confirm that the JAXB mappings generate the XML format we intend to parse.我们可以确认 JAXB 映射生成了我们打算解析的 XML 格式。

Parse 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}]

As you can see, the parsed data has all the values, and it matches the original data.如您所见,解析后的数据具有所有值,并且与原始数据匹配。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM