如何解析XML并使用SimpleXML将其存储在Map中?

Nen*_*nco 6 java android simple-framework

我在使用简单的xml框架解析xml时遇到了麻烦.我想在Map/hashMap中存储类别ID和锦标赛列表我该怎么做?我按照简单的xml教程,但它对我不起作用.

我将它存储在这样的列表中:

 @ElementList(entry = "Category", inline = true, required = false)
List<Category> category;
Run Code Online (Sandbox Code Playgroud)

但现在我想把它存放在地图上.

这是xml: 在此输入图像描述

我遵循的教程: 在此输入图像描述

任何帮助将不胜感激,tnx.

oll*_*llo 2

通过像or 这样的注释不可能的,但是使用 a仍然是一个(好的)选项@ElementList@ElementMapConverter

这样做意味着:实现一个转换器Tournaments,用于合并类别 ID/锦标赛列表对。

这是如何完成的:


首先是必要的(数据)类。

比赛:

@Root(name = "Tournament")
public class Tournament
{
    @Text
    private String data;

    public Tournament(String data)
    {
        this.data = data;
    }

    private Tournament() { /* Required */ }

    // ...
}
Run Code Online (Sandbox Code Playgroud)

注意:我给出了Tournament一些数据字符串,因为未显示真实数据。然而,实际上它包含什么数据并不重要。

类别:

@Root(name = "Category")
public class Category
{
    private String id;

    // ...
}
Run Code Online (Sandbox Code Playgroud)

锦标赛

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

    // ...
}
Run Code Online (Sandbox Code Playgroud)

@Convert使用以下内容Converter进行序列化/反序列化Tournaments。我没有在这个例子中实现序列化部分(但这并不困难)。

重要提示:需要(参见下面的示例)! @ConvertAnnotationStrategy

锦标赛转换器

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.");
    }

}
Run Code Online (Sandbox Code Playgroud)

所有的“魔法”都是由转换器完成的:

  1. 遍历所有Tournaments子节点
  2. 如果它是一个Category
    1. 获取id
    2. 迭代所有子项并将Tournament' 添加到列表中
    3. id/ 列表添加Tournament到结果中Tournaments

如上所示,可以使用Serializer节点的 for(反)序列化。无需手动实现。

例子

最后,这是一个例子。请注意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);
Run Code Online (Sandbox Code Playgroud)

输出:
使用生成的内容toString()添加到每个类中。

Tournaments{tournaments={289=[Tournament{data=aaaa}], 32=[Tournament{data=bbbd}, Tournament{data=cccc}]}}
Run Code Online (Sandbox Code Playgroud)