前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >Dom4j解析带有命名空间的XML文件

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

作者头像
卡尔曼和玻尔兹曼谁曼
发布于 2019-01-25 07:16:55
发布于 2019-01-25 07:16:55
2.3K00
代码可运行
举报
运行总次数:0
代码可运行

    今天我在解析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文件)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<?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 id="s_ylw-pushpin_hl">
		<IconStyle>
			<scale>1.3</scale>
			<Icon>
				<href>http://maps.google.com/mapfiles/kml/pushpin/grn-pushpin.png</href>
			</Icon>
			<hotSpot x="20" y="2" xunits="pixels" yunits="pixels"/>
		</IconStyle>
		<ListStyle>
		</ListStyle>
	</Style>
	<Style id="s_ylw-pushpin">
		<IconStyle>
			<scale>1.1</scale>
			<Icon>
				<href>http://maps.google.com/mapfiles/kml/pushpin/grn-pushpin.png</href>
			</Icon>
			<hotSpot x="20" y="2" xunits="pixels" yunits="pixels"/>
		</IconStyle>
		<ListStyle>
		</ListStyle>
	</Style>
	<StyleMap id="m_ylw-pushpin">
		<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打开,效果如下:

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

    实例如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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

    实例如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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());
		
	}
}

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

    运行结果如下:

    长安大学渭水校区

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

    实例如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class KMLReader2 {

	public static void main(String[] args) throws DocumentException {
		//方法二:设置你的DocumentFactory()的命名空间 setXPathNamespaceURIs
		Map<String, String> 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()指定你要使用的节点名和命名空间

    实例如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class KMLReader3 {

	public static void main(String[] args) throws DocumentException {
		// 不使用开发环境给你提供的一系列对象,而是用XPath语法中自带的local-name() 和 namespace-uri()
		// 指定你要使用的节点名和命名空间
		SAXReader reader = new SAXReader();
		Document document = reader.read(new File("长安大学渭水校区.kml"));

		Node name = document
				.selectSingleNode("//*[local-name()='name' and namespace-uri()='http://www.opengis.net/kml/2.2']");
		System.out.println(name.getText());
	}
}

    这里直接在XPath表达式中指出命名空间,local-name()代表元素名称,namespace-uri()代表元素所在命名空间。

    运行结果如下:

    长安大学渭水校区

    方法四:不使用XPath表达式,直接用element的element方法取一个子元素或elementIterator方法取多个元素

    实例如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class KMLReader4 {

	public static void main(String[] args) throws DocumentException {
		//不使用XPath,直接用element的element方法取一个子元素或elementIterator方法取多个元素
		SAXReader reader = new SAXReader();
		Document document = reader.read(new File("长安大学渭水校区.kml"));
		
		Element root = document.getRootElement();
		Element name = root.element("Document").element("name");
		System.out.println(name.getText());
	}
}

    这种方法是Dom4j的入门方法,这里不再叙述。

    运行结果如下:

    长安大学渭水校区

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2014年04月06日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Dom4j解析XML(详解)
DOM解析要求解析器将整个XML文件全部加载到内存中,生成一个Document对象。 1.优点:元素和元素之间保留结构,关系,可以针对元素进行增删改查操作。 2.缺点:如果XML文件过大,可能会导致内存溢出。
全栈程序员站长
2022/08/31
3.4K0
Dom4j解析XML(详解)
Java---XML的解析(2)-DOM4J解析/Xpath
Dom4j: Dom SUN dom在加载时,将所有元素全部加载内存 DOM4j - 第三方。
谙忆
2021/01/21
1.6K0
Java---XML的解析(2)-DOM4J解析/Xpath
dom4j 使用总结
dom4j是一个Java的XML API,类似于jdom,用来读写XML文件 dom4j的使用方法简单总结来说如下: ①可以创建一个新的xml文件 ②利用SAXReader和File对象创建一个已存在的xml文件的一个Document对象 ③利用Document对象的getRootElement()方法获取根节点,返回值类型为Element ④利用根节点,可以用迭代器遍历子节点,也可以直接利用XPATH语法查找节点,对节点元素、属性读取或更改 ⑤将更改写入xml文件保存 下面来看简单的实例: ①创建一个新的
欠扁的小篮子
2018/04/10
1.1K0
数据库技术:XML
XML -- Extensible Markup Language,即可扩展标记语言。
RendaZhang
2020/09/08
3K0
数据库技术:XML
技术经验|Java-Web基础之XML解析JAXP-dom4j
XML是标记型文档,js 使用 dom 解析标记型文档是根据 html 的层级结构,在内存中分配一个属性结构,把 html 的标签,属性和文本都封装成 document 对象、element 对象,属性对象、文本对象,node 节点对象。
六月暴雪飞梨花
2023/11/09
3380
技术经验|Java-Web基础之XML解析JAXP-dom4j
java dom4j 增删改查[通俗易懂]
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/159408.html原文链接:https://javaforall.cn
全栈程序员站长
2022/09/14
5220
Android 创建与解析XML(五)—— Dom4j方式
dom4j is an easy to use, open source library for working with XML, XPath and XSLT on the Java platform using the Java Collections Framework and with full support for DOM, SAX and JAXP. 
阳光岛主
2019/02/19
1.4K0
day07_02_XML解析思想
day07_02_XML解析思想 ============================================================================= XML解析: 解析xml可以做: 1. 如果xml作为配置文件:读取数据。 2. 如果xml作为传输文件:可写可读。 -------------------------------------- xml解析思想: DOM:将文档加载进内存,形成一颗dom树(document
黑泽君
2018/10/11
3430
dom4j Quick start
One of the first things you’ll probably want to do is to parse an XML document of some kind. This is easy to do in dom4j. The following code demonstrates how to this.
全栈程序员站长
2021/05/19
5580
JAVA基于dom4j实现对XML操作「建议收藏」
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/159196.html原文链接:https://javaforall.cn
全栈程序员站长
2022/09/14
3890
JAVA基于dom4j实现对XML操作「建议收藏」
java dom4j 查找_java dom4j根据条件读取查找xml节点的方法
大家好,又见面了,我是你们的朋友全栈君。 1.假如有下面的books.xml要用java dom4j解析查找。<?xml version=”1.0″ encoding=”UTF-8″?> Luce
全栈程序员站长
2022/09/17
1.6K0
工作中的坑——dom4j解析含有命名空间的XML的坑
网上大多数分析的帖子都说dom4j解析xml性能最好,所以在碰到实际业务场景中就着手使用dom4j来解析xml了。
Bug生活2048
2018/12/18
2.4K0
Java操作XML文件
DOM解析是一次性将整个XML文档加载进内存,在内存中构建Document的对象树,通过Document对象,得到树上的节点对象,通过节点对象访问(操作)到XML文档的内容。
全栈程序员站长
2022/09/08
1.5K0
Java实现——Dom4j读写XML文件
解析DOM4J是一个开源XML解析包,采用了Java集合框架并完全支持DOM,SAX和JAXP。最大的特色是使用了大量的接口,主要接口都在org.dom4j里定义。
全栈程序员站长
2022/09/14
1.3K0
Java实现——Dom4j读写XML文件
Java中使用DOM4J来生成xml文件和解析xml文件
一、前言 现在有不少需求,是需要我们解析xml文件中的数据,然后导入到数据库中,当然解析xml文件也有好多种方法,小编觉得还是DOM4J用的最多最广泛也最好理解的吧.小编也是最近需求里遇到了,就来整理一下自己的理解,只适合刚刚学习的,一起理解!今天我们把解析xml文件和生成xml文件在一起来展示. 二、准备依赖 <dependency> <groupId>dom4j</groupId> <artifactId>dom4j</artifactId> <version>1.
掉发的小王
2022/07/11
1.6K0
Java中使用DOM4J来生成xml文件和解析xml文件
Java – DOM4J解析XML文件[通俗易懂]
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/152040.html原文链接:https://javaforall.cn
全栈程序员站长
2022/08/31
2.3K0
Java – DOM4J解析XML文件[通俗易懂]
dom4j解析XML常用方法
基本使用 //读取xml SAXReader reader = new SAXReader(); Document document = reader.read(new File("input.xml")); // 获取根节点 Element root = document.getRootElement(); // 获取孩子节点 Iterator<Element> it1 = root.elementIterator(); // 获取属性 Iterator<Attribute> at
乱码三千
2021/07/29
9610
java中采用dom4j解析xml文件
在最近的开发中用到了dom4j来解析xml文件,以前听说过来解析xml文件的几种标准方式;但是从来的没有应用过来,所以可以在google中搜索dmo4j解析xml文件的方式,学习一下dom4j解析xml的具体操作。
全栈程序员站长
2022/06/24
7720
java中采用dom4j解析xml文件
基于DOM4J的XML文件解析类
XML文件解析分四类方式:DOM解析;SAX解析;JDOM解析;DOM4J解析。其中前两种属于基础方法,是官方提供的平台无关的解析方式;后两种属于扩展方法,它们是在基础的方法上扩展出来的,只适用于java平台。目前已经完成一种方式的封装基于DOM的XML文件解析类。
FunTester
2020/10/19
7290
xml解析系列(一)——用dom4j解析xml
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
逝兮诚
2019/10/30
3.1K0
xml解析系列(一)——用dom4j解析xml
相关推荐
Dom4j解析XML(详解)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验