XML是一种简单的数据存储语言,使用一系列简单的标记描述数据,而这些标记可以用方便的方式建立,虽然XML占用的空间比二进制数据要占用更多的空间,但XML极其简单易于掌握和使用。本文解析XML,分享给大家!
==================作者有话================
xml确实有点复杂,解析起来不仅耗内存,而且很复杂。这就好像花了几千块钱买了个MS Office,但是80%的feature都用不着,还白白的耗着CPU和内存。
个人觉得,设置文件用XML其实挺好,因为设置文件一般并不太大,而且要求可读性强,还有很多乱七八糟的需求,可以利用XML的力量。
前阵子做了个程序,需要解析豆瓣API调用返回的XML。真想说一句。。。豆瓣你别用XML了。。。至少,提供个on版的API调用吧。
(以上谨代表个人观点)
===================正文=================
解析豆瓣返回的xml,实在是不想用DOM这个重量级的玩意。DOM这个玩意,说它强大好还是说它官僚好呢。我倾向于使用SAXP解析。但是现在面临的一个问题是,我需要根据xml节点的名字和属性值(一个或者多个)来决定当前的值是不是我想要的。这就麻烦一点点。第一反应是考虑xpath。后来觉得不如自己做一个得了,权当是按需定制一个轻量级的xpath。
首先定义XMLSearchUnit类,这个类的实例用来描述一个需要在XML中搜索的值,值可以是xml节点的值,或者是节点的属性。
mzang
class XMLSearchUnit {
();
// if target is an attribute, then set this member to be the attribute name.
private String expectedAttr;
private String xmlPath;
public XMLSearchUnit(String xmlPath) {
xmlPath;
}
*/
publicboolean match(String path, Attributes attributes) {
false) {
returnfalse;
}
attributes.getValue(key);
false) {
returnfalse;
}
}
returntrue;
}
getAttributeMatchValidation() {
return attributeMatchValidation;
}
publicvoid addAttributeValidation(String key, String value) {
attributeMatchValidation.put(key, value);
}
public String getXmlPath() {
return xmlPath;
}
public attributeMatchValidation) {
attributeMatchValidation;
}
public String getExpectedAttr() {
return expectedAttr;
}
expectedAttr
*/
publicvoid setExpectedAttr(String expectedAttr) {
expectedAttr;
}
/**
* hash code can be cached if all properties are not be be changed.
*/
@Override
publicint hashCode() {
final31;
prime
* result
result
0 : xmlPath.hashCode());
return result;
}
@Override
publicboolean equals(Object obj) {
== obj)
returntrue;
null)
returnfalse;
obj.getClass())
return (XMLSearchUnit) obj;
null) {
null)
returnattributeMatchValidation
.equals(other.attributeMatchValidation))
returnfalse;
null) {
null)
returnexpectedAttr.equals(other.expectedAttr))
returnfalse;
null) {
null)
returnxmlPath.equals(other.xmlPath))
returnfalse;
return mzang
DefaultHandler {
publicstaticnew XMLSearchUnit(
);
publicstaticnew XMLSearchUnit(
);
publicstaticnew XMLSearchUnit(
);
publicstaticnew XMLSearchUnit(
);
publicstaticnew XMLSearchUnit(
);
publicstaticnew XMLSearchUnit(
);
publicstaticnew XMLSearchUnit(
);
);
}
();
// a counter of search unit. if it is 0, then all search unit finds a match
private0;
new StringBuilder();
privatestatic;
();
*/
parseResults(InputStream input,
XMLSearchUnit... expectedPath) {
null;
);
}
return results;
}
privatevoid addToPath(String addPath) {
path.append(pathSeparater).append(addPath.toLowerCase());
}
privatevoid popPath() {
path.lastIndexOf(pathSeparater);
path.delete(index, path.length());
}
@Override
public SAXException {
foundItems.clear();
0) {
return;
}
null;
// check if current node matches search units. if it is a node value
// search, then store it in a member variable named foundItems because
// the value of the node is known only when reaches the end of the
// node.but for attribute search, it value is known here. So then are
for (XMLSearchUnit unit : searchUnits) {
true) {
{
();
}
foundAttrItems.add(unit);
}
}
}
null) {
return;
}
attributes.getValue(attrUnit.getExpectedAttr());
;
}
}
/**
* if current node matches, the the node value is useful, store it.
*/
@Override
public length)
throws SAXException {
0) {
return;
}
0) {
return;
}
new String(ch, start, length);
;
}
results.put(unit, content);
}
}
@Override
publicvoid endElement(String uri, String localName, String qName)
throws SAXException {
foundItems.clear();
0) {
return;
}
popPath();
}
}