Java 在Android上计算文件中的XML元素
以如下格式的简单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
<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)关系。