XML命名空间的核心作用是避免不同XML文档或同一文档中不同模块的元素名称出现冲突,当多个来源的元素使用相同名称时,通过命名空间可以明确区分每个元素的所属范围。

XML命名空间的基本概念
XML命名空间通过统一资源标识符(URI)来唯一标识一个命名空间,通常URI是一个网址形式的字符串,但它仅作为唯一标识使用,不需要实际可访问。命名空间分为两种类型:默认命名空间和带前缀的命名空间。
默认命名空间
默认命名空间定义后,当前元素及其所有子元素如果没有显式指定其他命名空间前缀,都会属于这个默认命名空间。定义默认命名空间的语法是在元素上添加xmlns属性,示例如下:
<?xml version="1.0" encoding="UTF-8"?>
<book xmlns="http://www.ippipp.com/book">
<title>XML开发指南</title>
<author>张三</author>
<price>59.9</price>
</book>
上面的示例中,book、title、author、price所有元素都属于http://www.ippipp.com/book这个命名空间。
带前缀的命名空间
带前缀的命名空间需要先定义前缀和对应的URI的映射关系,之后使用该前缀的元素都属于对应的命名空间。定义方式为xmlns:前缀名="URI",示例如下:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<bk:book xmlns:bk="http://ipipp.com/book">
<bk:title>XML进阶教程</bk:title>
<bk:author>李四</bk:author>
</bk:book>
<prod:product xmlns:prod="http://ipipp.com/product">
<prod:name>笔记本</prod:name>
<prod:price>4999</prod:price>
</prod:product>
</root>
这个示例中,bk前缀对应图书相关的命名空间,prod前缀对应商品相关的命名空间,即使两个命名空间下都有price元素,也不会产生冲突。
命名空间的解析示例
在Java中解析带命名空间的XML时,需要开启命名空间感知,否则无法正确识别命名空间。以下是使用DOM解析上述带前缀命名空间XML的示例代码:
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import java.io.File;
public class XmlNamespaceParse {
public static void main(String[] args) throws Exception {
// 创建开启命名空间感知的DocumentBuilderFactory
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
// 解析XML文件
Document document = builder.parse(new File("test.xml"));
// 创建XPath对象
XPath xPath = XPathFactory.newInstance().newXPath();
// 查询bk命名空间下的title元素内容
String bookTitle = (String) xPath.evaluate("//bk:title", document, XPathConstants.STRING);
System.out.println("图书标题:" + bookTitle);
// 查询prod命名空间下的name元素内容
String productName = (String) xPath.evaluate("//prod:name", document, XPathConstants.STRING);
System.out.println("商品名称:" + productName);
}
}
运行上述代码会正确输出图书标题和商品名称,不会因为元素名称相同而出现错误。
命名空间使用注意事项
- 命名空间的URI只需要保证唯一性,不需要是实际可访问的网址,很多开发者会习惯使用自己公司的域名作为URI前缀。
- 子元素会继承父元素的默认命名空间,除非子元素显式定义了其他默认命名空间或者带前缀的命名空间。
- 属性默认不属于任何命名空间,除非给属性添加对应的命名空间前缀。
- 解析XML时如果没有开启命名空间感知,那么命名空间相关的定义会被当作普通属性处理,无法正确区分不同命名空间的元素。