一个没有引入Shema约束的XML文档
<?xml version="1.0" encoding="UTF-8"?> <书架> <书> <书名>JavaWeb开发大全</书名> <作者>班长</作者> <售价>99.8</售价> <简介>不错</简介> </书> <书> <书名>葵花宝典</书名> <作者>岳不群</作者> <售价>19.8</售价> <简介>欲练此功...</简介> </书> </书架>
直接使用如下代码利用XPath解析没有问题
public class Dom4jTest { public static void main(String[] args) throws Exception { run7(); } private static void run7() throws Exception { String uri = "src/book.xml"; //获取Document对象 Document doc = getDocument(uri); //获得此节点下的节点集合 List<Node> list = doc.selectNodes("/书架/书/作者"); //遍历list,输出所有节点的文本 list.forEach(tmp -> System.out.println(tmp.getText())); } private static Document getDocument(String uri) throws Exception { //新建解析器 SAXReader reader = new SAXReader(); //返回解析后的Document对象 return reader.read(uri); } }
输出结果为
班长 岳不群
若为XML引入Schema约束
<?xml version="1.0" encoding="UTF-8"?> <书架 xmlns="http://www.relic.com/Schematest" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.relic.com/Schematest book.xsd"> <书> <书名>JavaWeb开发大全</书名> <作者>班长</作者> <售价>99.8</售价> <简介>不错</简介> </书> <书> <书名>葵花宝典</书名> <作者>岳不群</作者> <售价>19.8</售价> <简介>欲练此功...</简介> </书> </书架>
此时,使用原来的方法进行解析,则发现没有结果,输出list的长度也为0.
查阅资料后发现,因为如果XML使用了名称空间,则XPath也要添加.
将代码修改如下:
public class Dom4jTest { public static void main(String[] args) throws Exception { run6(); } private static void run6() throws Exception { String uri = "src/book.xml"; //获取带有名称空间Document对象 Document doc = getXPathDocument(uri); //XPath书写时要带上自己设置的名称空间 List<Node> list = doc.selectNodes("/ns:书架/ns:书/ns:作者"); //遍历输出文本 list.forEach(tmp -> System.out.println(tmp.getText())); } private static Document getXPathDocument(String uri) throws Exception { //创建一个Map存储名称空间对应关系. Map<String, String> map = new HashMap<>(); map.put("ns", "http://www.relic.com/Schematest"); //将名称空间放入解析的Document中 DocumentFactory factory = new DocumentFactory(); factory.setXPathNamespaceURIs(map); SAXReader reader = new SAXReader(factory); //返回该Document对象 return reader.read(uri); } }
结果为
班长 岳不群