java - SAX Parser:如何仅从“Item”标签中读取?
问题描述
我正在使用 SAX Parser 来解析一些 XML 内容。请在下面检查我的代码。
public void parse(InputSource is, AppDataBean appDataBean) throws RuntimeException {
int limitCheck;
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
Log.d("SAX",appDataBean.getUrl());
DefaultHandler handler = new DefaultHandler() {
boolean title = false;
boolean link = false;
boolean author = false;
public void startElement(String uri, String localName,
String qName, Attributes attributes)
throws SAXException {
if (qName.equalsIgnoreCase(TITLE)) {
title = true;
}
if (qName.equalsIgnoreCase(LINK)) {
link = true;
}
if (qName.equalsIgnoreCase(AUTHOR)) {
author = true;
}
//Log.d("SAX","Start Element :" + qName);
}
public void endElement(String uri, String localName,
String qName)
throws SAXException {
}
public void characters(char ch[], int start, int length)
throws SAXException {
System.out.println(new String(ch, start, length));
if (title) {
Log.d("SAX","End Element :" + "First Name : "
+ new String(ch, start, length));
title = false;
}
if (link) {
Log.d("SAX","End Element :" + "Last Name : "
+ new String(ch, start, length));
link = false;
}
if (author) {
Log.d("SAX","End Element :" + "Nick Name : "
+ new String(ch, start, length));
author = false;
}
}
};
saxParser.parse(is, handler);
} catch (Exception e) {
e.printStackTrace();
}
}
下面是我的 XML 的样子。
<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
<?xml-stylesheet type="text/xsl" href="rss.xsl"?>
<channel>
<title>MyRSS</title>
<atom:link href="http://www.example.com/rss.php" rel="self" type="application/rss+xml" />
<link>http://www.example.com/rss.php</link>
<description>MyRSS</description>
<language>en-us</language>
<pubDate>Tue, 22 May 2018 13:15:15 +0530</pubDate>
<item>
<title>Title 1</title>
<pubDate>Tue, 22 May 2018 13:14:40 +0530</pubDate>
<link>http://www.example.com/news.php?nid=47610</link>
<guid>http://www.example.com/news.php?nid=47610</guid>
<description>bla bla bla</description>
</item>
</channel>
</rss>
但是在这里,我需要避免使用该Channel
标签,并且只读取根标签是Item
. 那么只有我才能得到真正的内容。我怎样才能做到这一点?
更新
正如答案所建议的那样,我尝试将 SAX Parser 与stack
. 下面是代码,但我还是不行,现在它什么也没打印First Name
public void parse(InputSource is, AppDataBean appDataBean) throws RuntimeException {
int limitCheck;
stack = new Stack<>();
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
Log.d("SAX", appDataBean.getUrl());
DefaultHandler handler = new DefaultHandler() {
boolean title = false;
boolean link = false;
boolean author = false;
public void startElement(String uri, String localName,
String qName, Attributes attributes)
throws SAXException {
Log.d("SAX", "localName: " + localName);
if(localName.equalsIgnoreCase("item"))
{
stack = new Stack<>();
stack.push(qName);
}
if (qName.equalsIgnoreCase(TITLE)) {
if(stack.peek().equalsIgnoreCase("item"))
{
title = true;
}
}
if (qName.equalsIgnoreCase(LINK)) {
link = true;
}
if (qName.equalsIgnoreCase(AUTHOR)) {
author = true;
}
//Log.d("SAX","Start Element :" + qName);
}
public void endElement(String uri, String localName,
String qName)
throws SAXException {
stack.pop();
}
public void characters(char ch[], int start, int length)
throws SAXException {
System.out.println(new String(ch, start, length));
if (title) {
Log.d("SAX", "End Element :" + "First Name : "
+ new String(ch, start, length));
title = false;
}
if (link) {
Log.d("SAX", "End Element :" + "Last Name : "
+ new String(ch, start, length));
link = false;
}
if (author) {
Log.d("SAX", "End Element :" + "Nick Name : "
+ new String(ch, start, length));
author = false;
}
}
};
saxParser.parse(is, handler);
} catch (Exception e) {
e.printStackTrace();
}
}
解决方案
通常,SAX 应用程序将维护一个堆栈来保存上下文。在 startElement 事件上,将元素名称压入堆栈;在 endElement 上将其从堆栈中弹出。然后,当您获得标题元素的 startElement 事件时,您可以执行 stack.peek() 以查看标题的父级是什么。
推荐阅读
- flutter - 更改材料按钮颜色 onPress 并返回默认 onLongPress
- google-apps-script - 在警报框的编辑触发器上
- r - 如何绘制具有重复 x 轴值的连续线
- python - 如何根据空白列删除 CSV 文件中的行
- javascript - JS中的数组仅运行最后一个方差值
- c# - 工作 1-2 小时后应用程序开始冻结且无响应
- python - 如何强制 python 在 macOS 上解锁文件
- flutter - 为 ListView.builder 中的每个孩子创建一个新的 BlocProvider 是不是一个坏主意?
- html - 如何在内容框上方放置图像?
- sampling - 如何估计蒙特卡洛路径跟踪器的方差?