JAVA - 从XML解析特定数据

时间:2016-05-05 21:38:51

标签: java xml sax

有很多页面在解释XML,但我还没有找到解决我特定问题的任何内容。我有一个XML文件,定义了我正在进行的简单游戏的所有项目。由于我不想随时加载整个地图,因此我也不需要随时加载游戏中的所有项目。只是我正在使用的地图部分中的那些。我理解SAX是最好的方法。基本上我想做的就是拥有这样的东西:

<item>
    <id>12345</id>
    <name>note</name>
    <weight>.1</weight>
</item>
<item>
     .......
</item>

我想编写一个函数,可以获取一个项目ID数组(从另一个特定于地图的列表中拉出我当时正在加载),以及每个id给出的解析通过xml文件,然后当找到其标记包含其要查找的ID的项标记时,从该项中的每个标记中获取数据并将其设置为我可以通过的变量(id,note和weight)到构造函数方法。这样,我只构建相关的项目和项目对象。但我不知道该怎么做。任何帮助都将受到高度赞赏。

编辑:

好吧,我想我只是弄明白这一点,但仍然遇到了问题。这就是我所拥有的

public class SaxParsing {

    public static void main(String argv[]) {

        try {
            SAXParserFactory factory = SAXParserFactory.newInstance();
            SAXParser saxParser = factory.newSAXParser();

            DefaultHandler handler = new DefaultHandler() {
                String foundName = null;
                int idGiven = 101002;
                boolean b_id = false;
                boolean b_idToFind = false;
                boolean b_name = false;

                @Override
                public void startElement(String uri, String localName, String qName, Attributes attributes)
                        throws SAXException {
                    if (localName.equalsIgnoreCase("id")) {
                        b_id = true;
                    }
                    if (localName.equalsIgnoreCase("name")) {
                        b_name = true;
                    }
                }

                @Override
                public void endElement(String uri, String localName, String qName) throws SAXException {
                    if (localName.equalsIgnoreCase("id")) {
                        b_id = false;
                    }
                    if (localName.equalsIgnoreCase("name")) {
                        b_name = false;
                    }
                    if (localName.equalsIgnoreCase("item")) {
                        b_idToFind = false;
                    }
                }

                public void characters(char buffer, int start, int length) throws SAXException {
                    if (b_id) {
                        String temp = new String();
                        temp = String.valueOf(buffer);
                        if (temp == Integer.toString(idGiven)) {
                            b_idToFind = true;
                        }
                    }
                    if (b_name) {
                        if (b_idToFind) {
                            foundName = new String();
                            foundName = String.valueOf(buffer);

                        }
                    }
                }
            };

            saxParser.parse("path\\to\\GameItems.xml", handler);
            System.out.println(foundName);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

一切正常,但我无法访问foundName之外的变量DefaultHandler。 NetBeans提供了一个无法找到符号的#34;错误。我觉得这是一个简单的范围问题,但我似乎无法解决它。

1 个答案:

答案 0 :(得分:1)

您无法访问pending,因为它是在foundName内部类中声明的。

你可以在内部类之外向上移动new DefaultHandler() { ... }两行,但是为了在内部类中访问它,你需要使它foundName,这使它成为没用你想要的东西。

您想要的是final,但handler.foundName被声明为handler类型,其中没有名为DefaultHandler的字段。您的内部类确实具有该字段,但该类型没有类型名称。有你的问题。解决方案是使它成为一个成熟的类:

foundName

然后,您可以将class ItemHandler extends DefaultHandler { String foundName; public void startElement(...) {...} public void endElement(...) {...} public void characters(...) {...} } 声明为handler类型,并获得访问其字段的权限:

ItemHandler

作为旁注。您的SAX处理存在缺陷。我们无法保证只需一次调用ItemHandler handler = new ItemHandler(); saxParser.parse("path\\to\\GameItems.xml", handler); System.out.println(handler.foundName); 注意正确的签名)即可获得代码<tag>yada,yada,yada</tag>之间的所有字符。您应该只累积它们,并在结束标记中处理它们。类似的东西:

public void characters(char[] ch, int start, int length)