0

我正在尝试使用简单 Java XML 解析器 (SJXP),但遇到了我需要解析为数据类的 XML 问题。

数据.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE SYSTEM "local-1.2.2.dtd" >
<data>
    <article>
        <field name="name" type="text">HOTELS</field>
        <field name="name_de" type="text">HOTELS</field>
        <field name="name_zh" type="text">酒店</field>
        <field name="color" type="text">6,68,109,0.85</field>
        <field name="textcolor" type="text">255,255,255,1</field>
    </article>
 <!-- 20000 more articles ... -->
</data>

我试图这样做:

xml处理程序.java

private Map<String, Category> categoryMap;

private XMLParser<Category> categoryParser = new XMLParser<Category>(
        new DefaultRule<Category>(IRule.Type.CHARACTER, "/data/article") {
            @Override
            public void handleParsedCharacters(XMLParser<Category> parser, String text, Category category) {

                Log.d("XmlHandler", "Hello");
                if (category != null) {
                    categoryMap.put(category.getName(Category.LANG.EN), category);
                    Log.d("XmlHandler", "Saved category to map. New count="+categoryMap.values().size());
                    category.reset();
                } else {
                    category = new Category();
                    Log.d("XmlHandler", "Creating a new category");
                }
            }
        },
        new CategoryNameRule()
);


private class CategoryNameRule extends DefaultRule<Category> {

    private String nameKey = "";

    public CategoryNameRule() {
        super(Type.ATTRIBUTE, "/data/article/field", "name");
    }

    @Override
    public void handleParsedAttribute(XMLParser parser, int index,
                                      String value, Category category) {
        nameKey = value;
    }

    @Override
    public void handleParsedCharacters(XMLParser parser, String text, Category category) {

        Log.d("XmlHandler", "Handling nameKey="+nameKey);

        if(nameKey == null || nameKey.length() == 0){
            return;
        }else if( "name".equals(nameKey)){
           category.setName(Category.LANG.EN, text);
        }else if( "name_de".equals(nameKey)){
           category.setName(Category.LANG.DE, text);
        }else if( "name_zh".equals(nameKey)){
           category.setName(Category.LANG.ZH, text);
        }else if( "color".equals(nameKey)){
           category.colorBackground = getConvertedColor(text);
        }else if( "textcolor".equals(nameKey)){
           category.colorForeground = getConvertedColor(text);
        }

    }
}

问题是我的哈希图在整个文档被解析后变成空的,我不知道为什么。我的猜测是我会结合 IRule.Type.CHARACTER 和 IRule.Type.ATTRIBUTE 但我不知道如何实现。

有什么想法/经验吗?

4

1 回答 1

0

Stefan,我很抱歉错过了这个问题(我在搜索其他内容时偶然通过谷歌找到了这个问题)。

这里有几点令人困惑,所以让我澄清一下,然后概述我建议如何解决这个问题(假设你没有找到方法,但我意识到这是 3 个月前)

首先,你是对的,你需要一个 CHARACTER 规则和 ATTRIBUTE 规则的组合。CHARACTER 规则将为您提供标签之间的内容,例如:

<tag>this is CHARACTER data</tag>

其次,您的规则应该针对包含您需要的数据的标签,在上面的示例中,在您到达 /data/article/field 级别之前,您似乎没有得到任何区分数据(各个字段同时包含 ATTRIBUTES 和 CHARACTERS你要)

看起来您关闭(打开标签)以告知您何时输入了新文章,因此您知道您正在为特定的、独特的文章收集字段信息。在这种情况下,您实际上可以在点击开始标签时使用 TAG 规则来归档,因此您可以执行一些逻辑,例如在 HashMap 中为即将解析的新文章创建新记录。

最后,您传递给处理程序的Category参数是一个传递用户变量。

这意味着您可以调用 Parse 方法:

XMLParser<List<Article>> p = new XMLParser<List<Article>>(... stuff ...);
List<Article> articleList = new ArrayList<Article>();

p.parse(input, articleList);

这允许您的所有处理程序直接访问您的 articleList,以便他们可以直接在其中解析/存储信息,因此当对 parse(...) 的调用返回时,您知道您的列表是最新的并已更新。

如果您没有向 userObject 字段中的 parse 方法传递任何内容,则处理程序都将收到一个参数。

您对Category的使用检查让我感到困惑,并让我认为您期望在调用处理程序时在那里获得变化的值,但事实并非如此。我只是想澄清一下。

概括

我认为您完美的解析器设计将包括 3 条规则:

  • /data/article TAG 规则——在遇到 START 文章标签时执行某些操作(并且可选地在遇到 CLOSE 文章标签时)。
  • /data/article/field CHARACTER 规则——存储字段的解析字符数据。
  • /data/article/field ATTRIBUTE 规则——存储字段的解析属性数据。

我希望这会有所帮助!

于 2013-03-12T21:28:08.287 回答