如何使用 Android 做一个简单的 XML 解析器
天哪,我已经被困在这个问题上有一段时间了。我知道这应该很简单,但我似乎找不到我哪里出错了。在遵循并尝试调整此处的 DOM 解析器示例后,我构建了我的小型 XML 解析器: http://www.ibm.com/developerworks/opensource/library/x-android/index.html 我让它识别节点,但我一生都无法弄清楚为什么这是告诉我节点的值为“null”。帮助将不胜感激。
我的 XML 测试文件。
<?xml version="1.0"?>
<Person>
<Name>Scott</Name>
<Gender>Male</Gender>
<More>And So On..</More>
</Person>
我的解析器代码是。
public class XMLParser {
InputStream xmlDocument;
TextView tv;
public XMLParser(InputStream xmlDocument, TextView tv) {
this.xmlDocument = xmlDocument;
this.tv = tv;
}
public HashMap<String, String> parse() {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
HashMap<String, String> xmlItems = new HashMap<String, String>();
try {
DocumentBuilder builder = factory.newDocumentBuilder();
Document dom = builder.parse(xmlDocument);
Element root = dom.getDocumentElement();
NodeList items = root.getElementsByTagName("Person");
Element rootElement = (Element)items.item(0);
items = rootElement.getChildNodes();
tv.append("\nParser, # of Items: " + String.valueOf(items.getLength()));
for (int i = 0; i < items.getLength(); i++){
Node item = items.item(i);
xmlItems.put(item.getNodeName(), item.getNodeValue());
tv.append("\nNM: " + item.getNodeName() + " NV: " + item.getNodeValue());
}
} catch (Exception e) {
throw new RuntimeException(e);
}
return xmlItems;
}
}
Hell there, I have been stuck on this for a bit now. I know it should be simple but I can't seem to find where I went wrong. I built my little XML parser after following and trying to adapt the DOM Parser example here: http://www.ibm.com/developerworks/opensource/library/x-android/index.html I have it recognising the nodes but I, for the life of me, can't figureout why it is telling me the value of the nodes is "null". Help would be greatly appreciated.
My XML test file.
<?xml version="1.0"?>
<Person>
<Name>Scott</Name>
<Gender>Male</Gender>
<More>And So On..</More>
</Person>
My Parser code is.
public class XMLParser {
InputStream xmlDocument;
TextView tv;
public XMLParser(InputStream xmlDocument, TextView tv) {
this.xmlDocument = xmlDocument;
this.tv = tv;
}
public HashMap<String, String> parse() {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
HashMap<String, String> xmlItems = new HashMap<String, String>();
try {
DocumentBuilder builder = factory.newDocumentBuilder();
Document dom = builder.parse(xmlDocument);
Element root = dom.getDocumentElement();
NodeList items = root.getElementsByTagName("Person");
Element rootElement = (Element)items.item(0);
items = rootElement.getChildNodes();
tv.append("\nParser, # of Items: " + String.valueOf(items.getLength()));
for (int i = 0; i < items.getLength(); i++){
Node item = items.item(i);
xmlItems.put(item.getNodeName(), item.getNodeValue());
tv.append("\nNM: " + item.getNodeName() + " NV: " + item.getNodeValue());
}
} catch (Exception e) {
throw new RuntimeException(e);
}
return xmlItems;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
我正在使用 XmlPullFactory,它还不错。
编辑以转换为哈希图
请注意,实际上并不推荐这样做。此代码不检查哈希图中的重复键,并且它将覆盖任何现有键!
I'm using XmlPullFactory, and it's not so bad.
Edit for Converting to Hashmap
Note that this isn't really recommended. This code does not check for duplicate keys in the hashmap, and it will overwrite any existing keys!!!
看起来Person实际上是这里的根节点,也许你不需要
root.getElementsByTagName("Person");
如果你计划有多个人可能将xml文件更改为然后更改它到
root.getElementsByTagName("Person");
It looks like Person is actually the root node here, maybe you don't need
root.getElementsByTagName("Person");
If your planning on having multiple people maybe change the xml file to and then change it to
root.getElementsByTagName("Person");
也许可以从 IBM 示例转向一个更简单的示例,如下所示:
http://p-xr. com/android-tutorial-how-to-parseread-xml-data-into-android-listview/
Maybe move away from the IBM example to a simpler example like this one:
http://p-xr.com/android-tutorial-how-to-parseread-xml-data-into-android-listview/
可以使用 SAX 解析器,例如:
Could use a SAX parser something like:
我发现 IBM 的示例笨重且混乱。我编写了自己的东西来处理 RSS 提要,它可以进行调整以适应自定义 XML 提要。
使用此示例:
将 此 yahoo feed 的内容保存到文件中并放置它在你的项目上。将文件读入字符串。
您现在有一个对象,其中包含 RSS 源中每个条目的列表
。下面有 4 个类。我为了自己的利益发表了一些评论,但可能会让其他人感到困惑。
基本上,
DefaultHandler
会在 XML 字符串中查找常见的 RSS 名称,例如描述、URL、标题等。它将每个条目保存到自己的对象中,并将其添加到主列表中。可以更改DefaultHandler
类中的常量(最终)字段(添加/删除字符串)以适合您的结构 - 尽管您可能需要更改XmlFeedItem
类的结构也。您应该能够在不更改标准 RSS 提要的情况下使用它。
希望有帮助
I found the IBM example clunky and messy. I wrote my own thing to handle RSS feeds, it can be adapted to accommodate custom XML feeds.
an example of using this:
save the contents of this yahoo feed into a file and place it on your project. read the file into a string.
you now have an object containing a list of each entry from the RSS feed
There are 4 classes below. I have commented some for my own good but it may be confusing for others.
Basically, the
DefaultHandler
looks through the XML string for common RSS names such as description, URL, title, etc. it saves each entry into its own object and adds it to the master list. the constant(final) fields in theDefaultHandler
class can be changed(add/remove strings) to fit your structure - although you may need to change the structure of theXmlFeedItem
class too.You should be able to use this with no changes to standard RSS feeds.
hope it helps
Stax/pull 确实很笨重,因为 API 级别相当低并且很难直接使用。请尝试 Konsume-XML :
这将打印
The Stax/pull is really clunky since the API is pretty low-level and hard to use directly. Please try Konsume-XML instead:
This will print
我分享是因为我没有找到关于这个答案的好的代码,并且我不会向我的项目添加另一个外部库,所以我做了一个简单的 XML 解析器来转换 XML ->列表
显然,通过使用这个概念,任何人都可以做出比这个更好的实现,哈哈,
我在 PhP 中做了另一个 XML 解析器,它只使用对象(php 在创建动态对象方面更自由。)如果有人需要,只需在上面写一条评论,我会分享它。
XML 解析递归函数来解析完整修剪的 XML 字符串(XML 标签之间没有空格,并且没有 \n 和 \t)并获取 HashMap 树列表(HashMap 树是一个 HashMap,它可以包含其他 HashMap,它可以包含其他 HashMap ecc埃克,
所以在代码中:
HashMap,其中 T 可以是 HashMap,或者例如 String
所以
HashMap>>
用法:
库代码:
(# LoL 于 10/07/2019 18:00 编辑 -> 添加“lastEvent”来管理空 XML 标签)
(# LoL 再次编辑 10/07/2019 18:52 -> 修复“lastEvent”管理空的 XML 标签)
它使用递归。
也许如果我需要的话,我会做一个 XML 解析器,将 XML 转换为通用对象。
为此,您需要在对象中使用“预先确定”“setter 和 getter”方法。
例如,对于每个标记 XML,您将有一个“getTAG_NAME()”和一个“setTAG_NAME”方法,您将使用它们来设置对象内的值。
为此,您需要使用 Java - Field 和 Method 类,例如使用名称设置对象字段:
因此,每次您有一个新的 XML_TAG 和一个新的 TAG_VALUE 时,您都可以通过以下方式调用相应的“setXML_TAG(TAG_VALUE)”方法 :使用上面的函数。
函数原型将类似于:
其中 T 是为存储 XML 标签值而构建的特定对象,例如:
如果您有类似 xml 的内容,那么您存储 XML 数据的对象将是:
那么当您获得 xml 标签时你只需做一个非常简单的例子(概念验证 [PoC):
显然要做到这一点,你需要在解析 XML 之前知道它是怎样的(当你不知道的时候?哈哈。显然你会知道它是怎样的,也许你会有不同的版本带有不同标签的 xml,但你总是知道你将得到的结构。)
实际上我个人使用 HashMaps Trees 方式只是因为我不喜欢创建很多类来解析 2 或 3 个 XML,所以实际上我没有实现对象方式。如果我愿意这样做,我会分享它。
GG
再见,祝你编码愉快!
(我希望是否有人使用递归函数发布其他解决方案,只是为了比较和学习更多方法(:谢谢!再见)
I share because I didn't found good codes about this answer and I won't add another external library to my project so I did a simple XML Parser which converts XML -> List
Obviously by using the concept anyone can do a better implementation than this lol
I did another XML parser in PhP which only use objects (php is more free about creating customized on the fly objects.) if anyone need just write a comment above and I will share it.
XML parsing recursive functions to parse a Full Trimmed XML String (No space between XML Tags and no \n and \t) and get a List of HashMaps Tree (an HashMap tree is an HashMap which can contains others HashMaps which can contains others HashMaps ecc ecc,
so in code:
HashMap where T can be HashMap or, for example, String
so
HashMap>>
Usage:
Library Code:
(# LoL Edited 10/07/2019 18:00 -> added "lastEvent" to manage empty XML tag)
(# LoL Edited Again 10/07/2019 18:52 -> fixed "lastEvent" to manage empty XML tags)
It uses recursion.
Maybe if I need I will do an XML parser which converts XML to Generic Objects.
To do that you need to use "pre-determinate" "setter & getter" methods in the Object.
For example for every tag XML you will have a "getTAG_NAME()" and a "setTAG_NAME" method which you will use to set the value inside the object.
To do that you need to use Java - Field and Method classes, for example to set a Object field using is name:
So every time you have a new XML_TAG and a new TAG_VALUE then you call the respective "setXML_TAG(TAG_VALUE)" method by using the function above.
The function prototype will be something like:
Where T is the specific object built to store the XML TAGs Value, for example:
If you have anything like the xml Above your object to store XML data will be:
So then when you get an xml tag you just do, really simple example (Proof-Of-Concept [PoC):
Obviously to do that you need to know how the XML is before parse it (when you won't know that? lol. Obviously you will know how it is, maybe you will have different versions of the xml with differents tags, but you will always know the structure you will get.)
Personally actually I'm using the HashMaps Trees way just because I don't like to create a lot of class just to parse 2 or 3 XMLs, so actually I didn't implemented the Object Way. If I will do that I will share it.
GG
Bye, have a Nice Coding!
(I'd like if anybody post others solution using recursive functions just to compare and learn more methods (: Thank you! bye all)