如何使用 SimpleXML 解析 XML 并将其存储在 Map 中?
How to parse XML and store it in a Map with SimpleXML?
我在使用简单的 xml 框架解析 xml 时遇到问题。我想在 Map/hashMap 中存储类别 ID 和锦标赛列表,我该怎么做?我遵循了关于简单 xml 的教程,但它对我不起作用。
我将它存储在这样的列表中:
@ElementList(entry = "Category", inline = true, required = false)
List<Category> category;
但现在我想将其存储在地图中。
这里是xml:
我遵循的教程:
感谢任何帮助,tnx。
问题是您正在尝试创建类似 Map<String, <List<Tournament>>
的结构,而使用 ElementMap
注释似乎无法实现。您需要某种 ElementMapList
注释。或许您可以 file an issue,Gallagher 先生可以补充一点。
像 @ElementList
或 @ElementMap
这样的 Annoations 不可能,但使用 Converter
仍然是 (好)选项。
这样做意味着:为 Tournaments
实现 Converter,合并 Category-Id / Tournament List 对。
这是如何完成的:
首先是必要的(数据-)classes.
锦标赛:
@Root(name = "Tournament")
public class Tournament
{
@Text
private String data;
public Tournament(String data)
{
this.data = data;
}
private Tournament() { /* Required */ }
// ...
}
注意: 我给了 Tournament
一些数据字符串,因为没有显示真实数据。然而,实际上它包含什么数据并不重要。
类别:
@Root(name = "Category")
public class Category
{
private String id;
// ...
}
锦标赛
@Root(name = "Tournaments")
@Convert(TournamentsConverter.class) // Specify the Converter used for this class
public class Tournaments
{
private Map<String, List<Tournament>> tournaments;
public Tournaments()
{
tournaments = new HashMap<>();
}
protected void put(String id, List<Tournament> tournaments)
{
this.tournaments.put(id, tournaments);
}
// ...
}
@Convert
将使用下面的Converter
进行Tournaments
的序列化/反序列化。我没有在这个例子中实现序列化部分(虽然不难)。
重要提示: @Convert
需要一个 AnnotationStrategy
(参见下面的示例)!
锦标赛转换器
public class TournamentsConverter implements Converter<Tournaments>
{
private final Serializer serializer = new Persister();
@Override
public Tournaments read(InputNode node) throws Exception
{
Tournaments tournaments = new Tournaments();
InputNode childNode = node.getNext();
// Iterate over all childs of 'Tournaments'
while( childNode != null )
{
if( childNode.getName().equals("Category") == true )
{
final String categoryId = childNode.getAttribute("category_id").getValue();
List<Tournament> tournamentList = new ArrayList<>();
InputNode child = childNode.getNext();
// Iterate over all childs of 'Category'
while( child != null )
{
// Use a Serializer to read the nodes data
Tournament tournament = serializer.read(Tournament.class, child);
tournamentList.add(tournament);
child = childNode.getNext();
}
// Insert the Id / Tournament's pair
tournaments.put(categoryId, tournamentList);
}
childNode = node.getNext();
}
return tournaments;
}
@Override
public void write(OutputNode node, Tournaments value) throws Exception
{
// Implement as needed
throw new UnsupportedOperationException("Not supported yet.");
}
}
所有"magic"都由转换器完成:
- 迭代所有
Tournaments
个子节点
- 如果是
Category
- 得到
id
- 遍历所有子项并将
Tournament
添加到列表
- 将
id
/ Tournament
的列表添加到结果 Tournaments
如上所示,可以使用 Serializer
对节点进行(反)序列化。无需手动实施。
例子
最后,举个例子。请注意 AnnotationStrategy
.
Serializer ser = new Persister(new AnnotationStrategy());
final String xml = "<Tournaments>\n"
+ " <Category category_id=\"289\">\n"
+ " <Tournament>aaaa</Tournament>\n"
+ " </Category>\n"
+ " <Category category_id=\"32\">\n"
+ " <Tournament>bbbd</Tournament>\n"
+ " <Tournament>cccc</Tournament>\n"
+ " </Category>\n"
+ "</Tournaments>";
Tournaments t = ser.read(Tournaments.class, xml);
System.out.println(t);
输出:
使用生成的 toString()
添加到每个 class.
Tournaments{tournaments={289=[Tournament{data=aaaa}], 32=[Tournament{data=bbbd}, Tournament{data=cccc}]}}
我在使用简单的 xml 框架解析 xml 时遇到问题。我想在 Map/hashMap 中存储类别 ID 和锦标赛列表,我该怎么做?我遵循了关于简单 xml 的教程,但它对我不起作用。
我将它存储在这样的列表中:
@ElementList(entry = "Category", inline = true, required = false)
List<Category> category;
但现在我想将其存储在地图中。
这里是xml:
我遵循的教程:
感谢任何帮助,tnx。
问题是您正在尝试创建类似 Map<String, <List<Tournament>>
的结构,而使用 ElementMap
注释似乎无法实现。您需要某种 ElementMapList
注释。或许您可以 file an issue,Gallagher 先生可以补充一点。
像 @ElementList
或 @ElementMap
这样的 Annoations 不可能,但使用 Converter
仍然是 (好)选项。
这样做意味着:为 Tournaments
实现 Converter,合并 Category-Id / Tournament List 对。
这是如何完成的:
首先是必要的(数据-)classes.
锦标赛:
@Root(name = "Tournament")
public class Tournament
{
@Text
private String data;
public Tournament(String data)
{
this.data = data;
}
private Tournament() { /* Required */ }
// ...
}
注意: 我给了 Tournament
一些数据字符串,因为没有显示真实数据。然而,实际上它包含什么数据并不重要。
类别:
@Root(name = "Category")
public class Category
{
private String id;
// ...
}
锦标赛
@Root(name = "Tournaments")
@Convert(TournamentsConverter.class) // Specify the Converter used for this class
public class Tournaments
{
private Map<String, List<Tournament>> tournaments;
public Tournaments()
{
tournaments = new HashMap<>();
}
protected void put(String id, List<Tournament> tournaments)
{
this.tournaments.put(id, tournaments);
}
// ...
}
@Convert
将使用下面的Converter
进行Tournaments
的序列化/反序列化。我没有在这个例子中实现序列化部分(虽然不难)。
重要提示: @Convert
需要一个 AnnotationStrategy
(参见下面的示例)!
锦标赛转换器
public class TournamentsConverter implements Converter<Tournaments>
{
private final Serializer serializer = new Persister();
@Override
public Tournaments read(InputNode node) throws Exception
{
Tournaments tournaments = new Tournaments();
InputNode childNode = node.getNext();
// Iterate over all childs of 'Tournaments'
while( childNode != null )
{
if( childNode.getName().equals("Category") == true )
{
final String categoryId = childNode.getAttribute("category_id").getValue();
List<Tournament> tournamentList = new ArrayList<>();
InputNode child = childNode.getNext();
// Iterate over all childs of 'Category'
while( child != null )
{
// Use a Serializer to read the nodes data
Tournament tournament = serializer.read(Tournament.class, child);
tournamentList.add(tournament);
child = childNode.getNext();
}
// Insert the Id / Tournament's pair
tournaments.put(categoryId, tournamentList);
}
childNode = node.getNext();
}
return tournaments;
}
@Override
public void write(OutputNode node, Tournaments value) throws Exception
{
// Implement as needed
throw new UnsupportedOperationException("Not supported yet.");
}
}
所有"magic"都由转换器完成:
- 迭代所有
Tournaments
个子节点 - 如果是
Category
- 得到
id
- 遍历所有子项并将
Tournament
添加到列表 - 将
id
/Tournament
的列表添加到结果Tournaments
- 得到
如上所示,可以使用 Serializer
对节点进行(反)序列化。无需手动实施。
例子
最后,举个例子。请注意 AnnotationStrategy
.
Serializer ser = new Persister(new AnnotationStrategy());
final String xml = "<Tournaments>\n"
+ " <Category category_id=\"289\">\n"
+ " <Tournament>aaaa</Tournament>\n"
+ " </Category>\n"
+ " <Category category_id=\"32\">\n"
+ " <Tournament>bbbd</Tournament>\n"
+ " <Tournament>cccc</Tournament>\n"
+ " </Category>\n"
+ "</Tournaments>";
Tournaments t = ser.read(Tournaments.class, xml);
System.out.println(t);
输出:
使用生成的 toString()
添加到每个 class.
Tournaments{tournaments={289=[Tournament{data=aaaa}], 32=[Tournament{data=bbbd}, Tournament{data=cccc}]}}