设为首页 加入收藏

TOP

Dom4j解析带有命名空间的XML文件(一)
2014-11-24 00:08:17 来源: 作者: 【 】 浏览:20
Tags:Dom4j 解析 带有 命名 空间 XML 文件

今天我在解析KML文件的过程中,使用XPath表达式,可是返回的结果总是null,纠结了很久,后来通过查资料,发现是我的KML中有命名空间的缘故。


首先,说明一些什么是KML,因为下面的例子中会用到KML。KML是Keyhole Markup Language的缩写,是一种基于XML 语法与格式的、用于描述和保存地理信息(如点、线、图像、多边形和模型等)的编码规范,可以被 Google Earth 和 Google Maps 识别并显示。Google Earth 和 Google Maps 处理 KML 文件的方式与网页浏览器处理 HTML 和 XML 文件的方式类似。Google Earth中通常使用KMZ文件,KMZ文件是压缩过的KML文件。目前,KML 是由开放地理空间联盟(Open Geospatial Consortium, Inc.,简称 OGC)维护的国际标准。


下面来看一个KML文件实例,即本文中要用到的XML文件:


(KML文件可以通过在Google Earth中得到,这里我利用Google Earth搜索长安大学渭水校区,然后添加地标,将位置另存为KML文件)


< xml version="1.0" encoding="UTF-8" >


长安大学渭水校区




normal
#s_ylw-pushpin


highlight
#s_ylw-pushpin_hl



长安大学渭水校区

108.9032130001538
34.36892100035922
0
8.682278169459107e-011
0
999.7995012938454
relativeToSeaFloor

#m_ylw-pushpin

1
108.9032130001538,34.36892100035922,0




KML文件可以使用Google Earth打开,效果如下:



现在进入正题,我们可以看到上面的XML文件包含命名空间,如果我们任然使用以前没有命名空间的方法用XPath获取节点元素会出现什么情况呢?


实例如下:


public class XMLReader {
public static void main(String[] args) throws DocumentException {
SAXReader reader = new SAXReader();
Document document = reader.read(new File("长安大学渭水校区.kml"));

Node name = document.selectSingleNode("//name");
if (name == null) {
System.out.println("name节点为null!");
} else {
System.out.println(name.getText());
}
}
}


运行结果如下:name节点为null!


可是我的name节点明明不为null呀,这都是命名空间惹的祸!


下面我们着重看看解决办法:


方法一:设置你的xpath的命名空间setNamespaceURIs


实例如下:


public class KMLReader1 {


public static void main(String[] args) throws DocumentException {
SAXReader reader = new SAXReader();
Document document = reader.read(new File("长安大学渭水校区.kml"));

//方法一:设置你的xpath的命名空间setNamespaceURIs
Map xmlMap = new HashMap<>();
xmlMap.put("default", "http://www.opengis.net/kml/2.2");
XPath xPath = document.createXPath("//default:name");
xPath.setNamespaceURIs(xmlMap);
Node name = xPath.selectSingleNode(document);
System.out.println(name.getText());

}
}


首先,声明一个Map对象,添加命名空间,Map的键为命名空间的名称,这里是默认命名空间所以这里Map的键可以随便取,我取名叫default,Map的值为命名空间的值,即http://www.opengis.net/kml/2.2。然后,声明一个XPath对象,在createXPath方法中,要使用带命名空间前缀的XPath表达式,即defau:name。最后,调用setNamespaceURIs方法,设置XPath的命名空间。


运行结果如下:


长安大学渭水校区


方法二:设置你的DocumentFactory()的命名空间 setXPathNamespaceURIs


实例如下:


public class KMLReader2 {


public static void main(String[] args) throws DocumentException {
//方法二:设置你的DocumentFactory()的命名空间 setXPathNamespaceURIs
Map xmlMap = new HashMap<>();
xmlMap.put("default", "http://www.opengis.net/kml/2.2");
xmlMap.put("gx", "http://www.google.com/kml/ext/2.2");

SAXReader reader = new SAXReader();
reader.getDocumentFactory().setXPathNamespaceURIs(xmlMap);
Document document = reader.read(new File("长安大学渭水校区.kml"));

Node name = document.selectSingleNode("//default:name");
System.out.println(name.getText());

Node altitudeMode = document.selectSingleNode("//gx:altitudeMode");
System.out.println(altitudeMode.getText());
}
}


这里,我们设置的不是XPath的命名空间了,而是DocumentFactory的命名空间,其原理都差不多,只不过作用范围不一样,设置XPath的命名空间作用在XPath表达式,设置DocumentFactory作用在整个Document对象上。所以这里不再啰嗦,和上面一样。


运行结果如下:


长安大学渭水校区


relativeToSeaFloor


方法三:不使用开发环境给你提供的一系列对象,而是用XPath语法中自带的local-name() 和 namespace-uri()指定你要使用的节点名和命名空间


实例如下

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Android连接到Linux/CentOS下Ecli.. 下一篇Java Swing中的透明窗体(Windows..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: