我正在尝试学习解析XML文档,我有一个使用命名空间的XML文档,所以,我确定我需要做一些事情才能正确解析.
这就是我所拥有的:
DefaultHandler handler = new DefaultHandler() {
boolean bfname = false;
boolean blname = false;
boolean bnname = false;
boolean bsalary = false;
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
System.out.println("Start Element :" + qName);
if (qName.equalsIgnoreCase("FIRSTNAME")) {
bfname = true;
}
if (qName.equalsIgnoreCase("LASTNAME")) {
blname = true;
}
if (qName.equalsIgnoreCase("NICKNAME")) {
bnname = true;
}
if (qName.equalsIgnoreCase("SALARY")) {
bsalary = true;
}
}
public void endElement(String uri, String localName,
String qName) throws SAXException {
System.out.println("End Element :" + qName);
}
public void characters(char ch[], int start, int length) throws SAXException {
if (bfname) {
System.out.println("First Name : " + new String(ch, start, length));
bfname = false;
}
if (blname) {
System.out.println("Last Name : " + new String(ch, start, length));
blname = false;
}
if (bnname) {
System.out.println("Nick Name : " + new String(ch, start, length));
bnname = false;
}
if (bsalary) {
System.out.println("Salary : " + new String(ch, start, length));
bsalary = false;
}
}
};
saxParser.parse(file, handler);
Run Code Online (Sandbox Code Playgroud)
我的问题是,在这个例子中我如何处理namespase?
要详细说明Blaise对示例代码的看法,请考虑这个人为的例子:
<?xml version="1.0" encoding="UTF-8"?>
<!-- ns.xml -->
<root xmlns:foo="http://data" xmlns="http://data">
<foo:record>ONE</foo:record>
<bar:record xmlns:bar="http://data">TWO</bar:record>
<record>THREE</record>
<record xmlns="http://metadata">meta 1</record>
<foo:record xmlns:foo="http://metadata">meta 2</foo:record>
</root>
Run Code Online (Sandbox Code Playgroud)
有两种不同类型的记录元素.一个在http://data命名空间中; http://metadata名称空间中的另一个.有三个数据记录和两个元数据记录.
该文件可以归一化为:
<?xml version="1.0" encoding="UTF-8"?>
<ns0:root xmlns:ns0="http://data" xmlns:ns1="http://metadata">
<ns0:record>ONE</ns0:record>
<ns0:record>TWO</ns0:record>
<ns0:record>THREE</ns0:record>
<ns1:record>meta 1</ns1:record>
<ns1:record>meta 2</ns1:record>
</ns0:root>
Run Code Online (Sandbox Code Playgroud)
但代码必须处理一般情况.
以下是一些用于打印元数据记录的代码:
class MetadataPrinter extends DefaultHandler {
private boolean isMeta = false;
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
isMeta = "http://metadata".equals(uri) && "record".equals(localName);
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
if (isMeta) {
System.out.println();
isMeta = false;
}
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
if (isMeta) {
System.out.print(new String(ch, start, length));
}
}
}
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware(true);
SAXParser parser = factory.newSAXParser();
parser.parse(new File("ns.xml"), new MetadataPrinter());
Run Code Online (Sandbox Code Playgroud)
注意:必须在某些较旧的Java XML API(其中包括SAX和DOM)中显式启用名称空间感知.
在命名空间限定的 XML 文档中,节点名称有两个组成部分:命名空间 URI 和本地名称(这些作为参数传递给 和startElement事件endElement)。当您检查某个元素是否存在时,您应该匹配这两个参数。目前,您的代码适用于下面的两个文档,即使它们的命名空间限定不同。
<foo xmlns="FOO">
<bar>Hello World</bar>
</foo>
Run Code Online (Sandbox Code Playgroud)
和
<foo xmlns="BAR">
<bar>Hello World</bar>
</foo>
Run Code Online (Sandbox Code Playgroud)
您当前(并且错误地)匹配了该qName参数。您所做的问题是,qName可能会根据用于表示名称空间的前缀而发生变化。下面的两个文档具有完全相同的命名空间限定。本地名称和命名空间相同,但它们的 QName 不同。
<foo xmlns="FOO">
<bar>Hello World</bar>
</foo>
Run Code Online (Sandbox Code Playgroud)
和
<ns:foo xmlns:ns="FOO">
<ns:bar>Hello World</ns:bar>
<ns:foo>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5331 次 |
| 最近记录: |