如何从 java 中的 xml 实体字符串值创建不同的 pojo
How to create a different pojo from xml entity string value in java
我的用例非常有限,而且我有很多限制。
首先,我只有一个 XML 的示例结构,定义如下。我没有架构定义。我的要求和实施在方法上受到很大限制。
<?xml version="1.0" encoding="UTF-8" ?>
<items>
<item>
<content_id>56789012</content_id>
<unique_record_id>B-123456</unique_record_id>
<title>ABC</title>
<type>board</type>
<dfield>098765</dfield>
<abn>11 222 333 444</abn>
<cfield>Yes</cfield>
<bfield>Goodness me</bfield>
<afield>ABCD</afield>
</item>
<item>
<content_id>1234</content_id>
<unique_record_id>D-789</unique_record_id>
<title>Member</title>
<type>role</type>
<contact>90000</contact>
<role_belongs_to>56789012</role_belongs_to>
<updated>23/07/2018 - 3:30pm</updated>
<importance>90</importance>
</item>
<item>
<content_id>90000</content_id>
<unique_record_id>D-654321</unique_record_id>
<title>Someone Else</title>
<type>person</type>
<salutation>Ms.</salutation>
<first_name>Someone</first_name>
<last_name>Else</last_name>
</item>
.
.
.
.
.
</items>
上面的模型是 xml 我将得到的简单表示(不,我不是在处理个人、公司数据模型:))。请注意,有许多项目类型。 type 字段实际上是我要创建的 POJO。项目之间也有关系。请注意,关系通常是一对多。
即
- 一个人可以扮演很多角色
- 一个人可以为多个董事会工作
- 一个人可以为很多组织工作
也有一对一的关系,即:
- 一个角色只能属于1个组织
- 还有其他几个.....
我的目标:
- 我想知道提取所有关系的最干净的方法
- 为所有项目创建关联的 pojo 列表
pojo类型
- 将 xml 反规范化为下面定义的新 xml 结构样本。
我知道我可以编写相当多的代码来剥离 xml 并在 xml 解组和迭代后使用反射创建 POJO。
我正在寻找最简洁的方法,我对 JAXB、SAX 或任何其他可以简化手头任务的库持开放态度。
非规范化输出示例:
<?xml version="1.0" encoding="UTF-8" ?>
<items>
<Person>
<content_id>90000</content_id>
<unique_record_id>D-654321</unique_record_id>
<title>Someone Else</title>
<salutation>Ms.</salutation>
<first_name>Someone</first_name>
<last_name>Else</last_name>
<role>
<content_id>1234</content_id>
<unique_record_id>D-789</unique_record_id>
<title>Member</title>
<role_belongs_to>
<board>
<content_id>56789012</content_id>
<unique_record_id>B-123456</unique_record_id>
<title>ABC</title>
<dfield>098765</dfield>
<abn>11 222 333 444</abn>
<cfield>Yes</cfield>
<bfield>Goodness me</bfield>
<afield>ABCD</afield>
</board>
</role_belongs_to>
<updated>23/07/2018 - 3:30pm</updated>
<importance>90</importance>
</role>
</Person>
.
.
</items>
有趣的需求组合。我让它与 SimpleXml 一起工作。如果你觉得这足够干净,这取决于你。首先是一些 POJO:
public class Items {
@XmlName("item")
@XmlAbstractClass(tag="type", types={
@TypeMap(name="board", type=Board.class),
@TypeMap(name="role", type=Role.class),
@TypeMap(name="person", type=Person.class)
})
public List<Item> items;
}
abstract class Item {
@XmlName("content_id")
public Integer contentId;
}
public class Board extends Item {
String abn;
}
public class Role extends Item {
@XmlNoExport
@XmlName("role_belongs_to")
Integer boardId;
@XmlNoImport
@XmlWrapperTag("role_belongs_to")
Board board;
}
public class Person extends Item {
@XmlNoExport
@XmlName("has_role")
public Integer hasRole;
@XmlNoImport
public Role role;
}
@XmlName("items")
public class PersonList {
@XmlName("Person")
public List<Person> persons;
}
接下来我们将 xml 序列化为项目列表:
final SimpleXml simple = new SimpleXml();
final Items items = simple.fromXml(xml, Items.class);
然后我们需要在内存中移动一些:
final Map<Integer, Board> boards = new HashMap<>();
items.items.forEach(item -> { if (item instanceof Board) boards.put(item.contentId, (Board)item); });
final Map<Integer, Role> roles = new HashMap<>();
items.items.forEach(item -> { if (item instanceof Role) roles.put(item.contentId, (Role)item); });
final List<Person> persons = new ArrayList<>();
items.items.forEach(item -> { if (item instanceof Person) persons.add((Person)item); });
roles.values().forEach(role -> role.board = boards.get(role.boardId));
persons.forEach(person -> person.role = roles.get(person.hasRole));
最后序列化结果并打印:
final PersonList pl = new PersonList();
pl.persons = persons;
System.out.println(simple.toXml(pl));
应该打印出你想要的。我不太明白你是如何为 Persons 分配角色的,所以我创建了一个 has_role
字段并使用了它。当然你可以做任何事情。
SimpleXml 在 Maven 中心:
<dependency>
<groupId>com.github.codemonstur</groupId>
<artifactId>simplexml</artifactId>
<version>1.5.5</version>
</dependency>
我的用例非常有限,而且我有很多限制。
首先,我只有一个 XML 的示例结构,定义如下。我没有架构定义。我的要求和实施在方法上受到很大限制。
<?xml version="1.0" encoding="UTF-8" ?>
<items>
<item>
<content_id>56789012</content_id>
<unique_record_id>B-123456</unique_record_id>
<title>ABC</title>
<type>board</type>
<dfield>098765</dfield>
<abn>11 222 333 444</abn>
<cfield>Yes</cfield>
<bfield>Goodness me</bfield>
<afield>ABCD</afield>
</item>
<item>
<content_id>1234</content_id>
<unique_record_id>D-789</unique_record_id>
<title>Member</title>
<type>role</type>
<contact>90000</contact>
<role_belongs_to>56789012</role_belongs_to>
<updated>23/07/2018 - 3:30pm</updated>
<importance>90</importance>
</item>
<item>
<content_id>90000</content_id>
<unique_record_id>D-654321</unique_record_id>
<title>Someone Else</title>
<type>person</type>
<salutation>Ms.</salutation>
<first_name>Someone</first_name>
<last_name>Else</last_name>
</item>
.
.
.
.
.
</items>
上面的模型是 xml 我将得到的简单表示(不,我不是在处理个人、公司数据模型:))。请注意,有许多项目类型。 type 字段实际上是我要创建的 POJO。项目之间也有关系。请注意,关系通常是一对多。
即
- 一个人可以扮演很多角色
- 一个人可以为多个董事会工作
- 一个人可以为很多组织工作
也有一对一的关系,即:
- 一个角色只能属于1个组织
- 还有其他几个.....
我的目标:
- 我想知道提取所有关系的最干净的方法
- 为所有项目创建关联的 pojo 列表 pojo类型
- 将 xml 反规范化为下面定义的新 xml 结构样本。
我知道我可以编写相当多的代码来剥离 xml 并在 xml 解组和迭代后使用反射创建 POJO。
我正在寻找最简洁的方法,我对 JAXB、SAX 或任何其他可以简化手头任务的库持开放态度。
非规范化输出示例:
<?xml version="1.0" encoding="UTF-8" ?>
<items>
<Person>
<content_id>90000</content_id>
<unique_record_id>D-654321</unique_record_id>
<title>Someone Else</title>
<salutation>Ms.</salutation>
<first_name>Someone</first_name>
<last_name>Else</last_name>
<role>
<content_id>1234</content_id>
<unique_record_id>D-789</unique_record_id>
<title>Member</title>
<role_belongs_to>
<board>
<content_id>56789012</content_id>
<unique_record_id>B-123456</unique_record_id>
<title>ABC</title>
<dfield>098765</dfield>
<abn>11 222 333 444</abn>
<cfield>Yes</cfield>
<bfield>Goodness me</bfield>
<afield>ABCD</afield>
</board>
</role_belongs_to>
<updated>23/07/2018 - 3:30pm</updated>
<importance>90</importance>
</role>
</Person>
.
.
</items>
有趣的需求组合。我让它与 SimpleXml 一起工作。如果你觉得这足够干净,这取决于你。首先是一些 POJO:
public class Items {
@XmlName("item")
@XmlAbstractClass(tag="type", types={
@TypeMap(name="board", type=Board.class),
@TypeMap(name="role", type=Role.class),
@TypeMap(name="person", type=Person.class)
})
public List<Item> items;
}
abstract class Item {
@XmlName("content_id")
public Integer contentId;
}
public class Board extends Item {
String abn;
}
public class Role extends Item {
@XmlNoExport
@XmlName("role_belongs_to")
Integer boardId;
@XmlNoImport
@XmlWrapperTag("role_belongs_to")
Board board;
}
public class Person extends Item {
@XmlNoExport
@XmlName("has_role")
public Integer hasRole;
@XmlNoImport
public Role role;
}
@XmlName("items")
public class PersonList {
@XmlName("Person")
public List<Person> persons;
}
接下来我们将 xml 序列化为项目列表:
final SimpleXml simple = new SimpleXml();
final Items items = simple.fromXml(xml, Items.class);
然后我们需要在内存中移动一些:
final Map<Integer, Board> boards = new HashMap<>();
items.items.forEach(item -> { if (item instanceof Board) boards.put(item.contentId, (Board)item); });
final Map<Integer, Role> roles = new HashMap<>();
items.items.forEach(item -> { if (item instanceof Role) roles.put(item.contentId, (Role)item); });
final List<Person> persons = new ArrayList<>();
items.items.forEach(item -> { if (item instanceof Person) persons.add((Person)item); });
roles.values().forEach(role -> role.board = boards.get(role.boardId));
persons.forEach(person -> person.role = roles.get(person.hasRole));
最后序列化结果并打印:
final PersonList pl = new PersonList();
pl.persons = persons;
System.out.println(simple.toXml(pl));
应该打印出你想要的。我不太明白你是如何为 Persons 分配角色的,所以我创建了一个 has_role
字段并使用了它。当然你可以做任何事情。
SimpleXml 在 Maven 中心:
<dependency>
<groupId>com.github.codemonstur</groupId>
<artifactId>simplexml</artifactId>
<version>1.5.5</version>
</dependency>