Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在Android上计算文件中的XML元素_Java_Xml_Android - Fatal编程技术网

Java 在Android上计算文件中的XML元素

Java 在Android上计算文件中的XML元素,java,xml,android,Java,Xml,Android,以如下格式的简单XML文件为例: <Lists> <List> <Note/> ... <Note/> </List> <List> <Note/> ... <Note/> </List> </Lists> private void pullParserSample(FileInputStream xml) { int lists = 0; int notes

以如下格式的简单XML文件为例:

<Lists>
<List>
<Note/>
...
<Note/>
</List>
<List>
<Note/>
...
<Note/>
</List>
</Lists>
private void pullParserSample(FileInputStream xml) {
    int lists = 0;
    int notes = 0;
    int eventType = -1;

    try {
        XmlPullParser xpp = XmlPullParserFactory.newInstance().newPullParser();
        xpp.setInput(new InputStreamReader(xml));

        eventType = xpp.getEventType();

        do {
            switch ( eventType ) {

            case XmlPullParser.START_TAG:
                final String tag = xpp.getName();
                if ( "Note".equals(tag) ) {
                    notes++;
                }
                else if ( "List".equals(tag) ) {
                    lists++;
                }
                break;

            }

        } while ((eventType = xpp.next()) != XmlPullParser.END_DOCUMENT) ;

    } catch (XmlPullParserException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    Log.d(TAG, "lists=" + lists + " notes=" + notes);
}

...
...
每个节点都有一些实际保存文件数据的属性。我需要一种非常快速的方法来计算每种类型元素的数量(列表和注释)。列表只是根,并不重要

我可以通过简单的字符串搜索或类似的方法来实现这一点,但我需要尽可能快地实现这一点

设计参数:
必须使用java(Android应用程序)。
必须尽量避免分配内存。
无论文件中的位置如何,都必须返回文件中注释元素的总数和列表元素的数量

列表的数量通常很小(1-4),每个文件的注释数量可能非常大(超过1000个,通常为100个)


我期待着您的建议。

看看如何实现org.xml.sax.ContentHandler并将其发送到org.xml.sax.XMLReader


这些类与Android SDK捆绑在一起。这是一种“前向解析器”方法,当文档从头到尾被处理时,ContentHandler会显示每个XML元素(标记、属性、文本)。前向解析器的方法在内存使用方面很轻,比构建DOM快得多。

如果您只想计算文本中的元素,而不是解析文档,那么您可以按顺序读取文件中的每一行,并使用Pattern/Matcher类(我忘了是哪个)检查该行是否匹配“
”或“
”和分别递增计数器

编辑:另一个想法


当遇到StringBuilder的“”字符时,请逐个阅读文档。然后,当遇到“>”符号时,将StringBuilder字符串与“Note”或“List”或其他符号进行比较,并相应地递增计数器。最后,清除StringBuilder并重复此操作,直到文档结束。

使用由生成的状态机快速清除未测试的解决方案。 将此信息提供给ragel,ragel将为您生成java代码

生成的代码将使用基于表的FSM解析器,该解析器具有恒定的内存需求(表和状态变量)。它还可以接受部分数据,您可以在任何位置恢复它

这可能比任何通用解析器或系统的正则表达式都要快

(免责声明:我不是Java程序员,下面的代码也不完整,因为它缺少运行所需的框架代码。不过,这可能是一个不错的起点。)

%%{
机器节点计数器;
注意='是一个流式pull XML解析器,当需要快速有效地处理所有输入元素时,应该使用它

您可以尝试以下方法:

<Lists>
<List>
<Note/>
...
<Note/>
</List>
<List>
<Note/>
...
<Note/>
</List>
</Lists>
private void pullParserSample(FileInputStream xml) {
    int lists = 0;
    int notes = 0;
    int eventType = -1;

    try {
        XmlPullParser xpp = XmlPullParserFactory.newInstance().newPullParser();
        xpp.setInput(new InputStreamReader(xml));

        eventType = xpp.getEventType();

        do {
            switch ( eventType ) {

            case XmlPullParser.START_TAG:
                final String tag = xpp.getName();
                if ( "Note".equals(tag) ) {
                    notes++;
                }
                else if ( "List".equals(tag) ) {
                    lists++;
                }
                break;

            }

        } while ((eventType = xpp.next()) != XmlPullParser.END_DOCUMENT) ;

    } catch (XmlPullParserException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    Log.d(TAG, "lists=" + lists + " notes=" + notes);
}

这个问题不是代码高尔夫,而是一个现实问题。删除“代码高尔夫”tags.Sax需要太长的时间,因为它解析所有内容。我只需要计算节点,必须有一个更有效的方法。你是说使用正则表达式吗?在Android上这些非常昂贵。不一定需要正则表达式,如果标记在自己的行上,那么你可以从行中删除空白,只使用String.equals()方法。这些字符串方法需要内存分配,这在移动设计中同样很重要,要避免。将分配一些内存,但如果可能,应该避免使用O(n)关系。