java学习脚印:SAX解析xml时命名空间以及参数问题
本文以实例形式解释下java利用SAX解析xml时命名空间及其参数问题。
(关于xml使用及命名空间的详细展开,可以参考W3school官方教程,这里提供的是关于主题的敏捷版)
1.命名空间直观感受
首先对命名空间有个直观感受,请看下面的未使用命名空间的xml代码。
清单1-1 :books.xml
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book>
<title>Harry Potter</title>
<author>J K. Rowling</author>
</book>
<book>
<title>Learning XML</title>
<author>Erik T. Ray</author>
</book>
</books>
然后请看下面使用了命名空间的xml代码。
清单1-2: NameSpaceDemo.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--命名空间示例-->
<books>
<!--使用前缀命名空间-->
<jd:book xmlns:jd="http://www.jd.com">
<jd:title>Harry Potter</jd:title>
<jd:author>J K. Rowling</jd:author>
</jd:book>
<!--使用默认命名空间-->
<book xmlns="http://www.dangdang.com">
<title>Learning XML</title>
<author>Erik T. Ray</author>
</book>
</books>
这里关键几个概念是:
命名空间标识符NamespaceIdentifier
命名空间与java中包机制类似,用来避免在同一文件中包含相同名称但结构不同的元素时可能出现的冲突。命名空间标识符可以使用URL以及其他方式,本例中对应的标识符是http://www.jd.com http://www.dangdang.com
命名空间前缀Prefix
前缀就是命名空间的快捷引用方式,它也称作命名空间的别名(alias)。
本例中对应的是 jd
不带前缀和命名空间的本地名称LocalName (Part)
本例中是booktitle author。
带有别名前缀的限定名QualifiedName (qName)
由别名前缀,冒号以及元素名称组成,这些名称很清晰,可被解析器解析和验证。
本例中是jd:book jd:title
就是省去前缀的命名空间,这样在后续的书写时就不用带上前缀了。例如本例中的
<book xmlns="http://www.dangdang.com">
<title>Learning XML</title>
<author>Erik T. Ray</author>
</book>
使用的就是默认命名空间。
2.java SAX解析xml参数问题
这里尤其以方法,public void startElement(String uri, String localName, String qName, Attributes attributes) 为例.
uri- 代表命名空间的标识符,当元素没有命名空间或者解析器的命名空间支持特性没有打开时是空串。注意,可以使用SAXParserFactory的public void setNamespaceAware(boolean awareness)打开支持命名空间特性。
localName - 代表没有前缀的本地名,当支持命名空间特性没有打开时是空串。
qName - 代表带有前缀的限定名,当限定名不能获取时是空串。
attributes - 与元素相关的属性,如果没有属性,那么就是空的属性对象。
下面给出解析上面带有命名空间的xml文档的实例代码,通过观察结果,更好的理解上述参数。
代码清单:SAXTest.java
package com.learningjava;
import java.io.File;
import java.util.ArrayList;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
/**
* This program illustrate using SAX to parser xml
* @author wangdq
* 2011-11-7
*/
public class SAXTest {
public static void main(String[] args) throws Exception {
//step1 : get a parser
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware(true);//performe Namespace processing
SAXParser parser = factory.newSAXParser();
//step2: create a handler
DefaultHandler handler = new DefaultHandler(){
@Override
public void startElement (String uri, String localName,
String qName, Attributes attributes) throws SAXException
{
System.out.format("uri: %-25s\tlocalname: %-10s\tqname: %-10s%n",uri,localName,qName);
if(localName.equals("title")) {
title = true;
}
}
@Override
public void endElement(String namespaceURI, String localName, String qName)
throws SAXException {
// End of processing current element
if (title) {
title = false;
}
}
@Override
public void characters(char[] ch, int start, int length) {
// Processing character data inside an element
if (title) {
String bookTitle = new String(ch, start, length);
bookList.add(bookTitle);
}
}
@Override
public void endDocument ()throws SAXException{
System.out.println("we have books: "+bookList);
}
ArrayList<String> bookList = new ArrayList<>();
private boolean title =false;
};
//step3 attach a handler and begin Parsing the xml
parser.parse(new File("NameSpaceDemo.xml"), handler);
}
}
运行结果
uri: localname: books qname: books
uri: http://www.jd.com localname: book qname: jd:book
uri: http://www.jd.com localname: title qname: jd:title
uri: http://www.jd.com localname: author qname: jd:author
uri: http://www.dangdang.com localname: book qname: book
uri: http://www.dangdang.com localname: title qname: title
uri: http://www.dangdang.com localname: author qname: author
we have books: [Harry Potter, Learning XML]
通过观察结果,相信现在对命名空间及SAX解析时的参数有了一个较好的理解。