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"?>
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">
<Document>
 <name>长安大学渭水校区</name>
 <Style>
  <IconStyle>
   <scale>1.3</scale>
   <Icon>
    <href></href>
   </Icon>
   <hotSpot x="20" y="2" xunits="pixels" yunits="pixels"/>
  </IconStyle>
  <ListStyle>
  </ListStyle>
 </Style>
 <Style>
  <IconStyle>
   <scale>1.1</scale>
   <Icon>
    <href></href>
   </Icon>
   <hotSpot x="20" y="2" xunits="pixels" yunits="pixels"/>
  </IconStyle>
  <ListStyle>
  </ListStyle>
 </Style>
 <StyleMap>
  <Pair>
   <key>normal</key>
   <styleUrl>#s_ylw-pushpin</styleUrl>
  </Pair>
  <Pair>
   <key>highlight</key>
   <styleUrl>#s_ylw-pushpin_hl</styleUrl>
  </Pair>
 </StyleMap>
 <Placemark>
  <name>长安大学渭水校区</name>
  <LookAt>
   <longitude>108.9032130001538</longitude>
   <latitude>34.36892100035922</latitude>
   <altitude>0</altitude>
   <heading>8.682278169459107e-011</heading>
   <tilt>0</tilt>
   <range>999.7995012938454</range>
   <gx:altitudeMode>relativeToSeaFloor</gx:altitudeMode>
  </LookAt>
  <styleUrl>#m_ylw-pushpin</styleUrl>
  <Point>
   <gx:drawOrder>1</gx:drawOrder>
   <coordinates>108.9032130001538,34.36892100035922,0</coordinates>
  </Point>
 </Placemark>
</Document>
</kml>

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

Dom4j解析带有命名空间的XML文件

现在进入正题,我们可以看到上面的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<String, String> 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());
 
 }
}

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/9967bb8d430ad596d5498e50e8e88d5a.html