首页
登录 | 注册

Dom4J配合XPath解析schema约束的xml配置文件问题

如果一个xml文件没有引入约束,或者引入的是DTD约束时,那么使用dom4j和xpath是可以正常解析的,不引入约束的情况本文不再展示。

引入DTD约束的情况

  • mybook.dtd:
<?xml version="1.0" encoding="UTF-8" ?>
<!ELEMENT books (book+)>
<!ELEMENT book (name|author|price)+>
<!ELEMENT name (#PCDATA)>
<!ELEMENT author (#PCDATA)>
<!ELEMENT price (#PCDATA)>
<!ATTLIST book id ID #REQUIRED publish CDATA #IMPLIED>
  • book.xml:
<?xml version="1.0" encoding="UTF-8 ?>
<!DOCTYPE books SYSTEM "mybook.dtd">
<books>
    <book id="_001">
        <name>西游记</name>
    </book>
    <book id="_002">
        <name>三国演义</name>
    </book>
    <book id="_003">
        <name>水浒传</name>
    </book>
    <book id="_004">
        <name>红楼梦</name>
    </book>
</books>

测试类:

public class DemoBook {
    public static void main(String[] args) throws DocumentException {
        SAXReader reader = new SAXReader();
        Document document = reader.read(DemoBook.class.getResourceAsStream("book.xml"));
        List<Node> nodes = document.selectNodes("//name");
        for (Node node : nodes) {
            Element element = (Element) node;
            System.out.print(element.getText()+" ");
        }
    }
}

//输出结果:西游记 三国演义 水浒传 红楼梦 

可见,引入了DTD约束的xml是可以通过dom4j和xpath表达式正常解析的.而引入Schema约束的时候呢?

引入Schema约束的情况

  • mybook.xsd:
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://www.mytest.com/book"
    elementFormDefault="qualified">
    <element name="books">
        <complexType>
            <sequence maxOccurs="unbounded">
                <element name="book">
                    <complexType>
                        <choice maxOccurs="unbounded">
                            <element name="name" type="string"></element>
                            <element name="author" type="string"></element>
                        </choice>
                    </complexType>
                </element>
            </sequence>
        </complexType>
    </element>
</schema>
  • book.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<books
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://www.mytest.com/book"
        xsi:schemaLocation="http://www.mytest.com/book /mybook.xsd"
>
    <book>
        <name>西游记</name>
    </book>
    <book>
        <name>三国演义</name>
    </book>
    <book>
        <name>水浒传</name>
    </book>
    <book>
        <name>红楼梦</name>
    </book>
</books>

测试类:

public class DemoBook {
    public static void main(String[] args) throws DocumentException {
        SAXReader reader = new SAXReader();
        Document document = reader.read(DemoBook.class.getResourceAsStream("book.xml"));
        List<Node> nodes = document.selectNodes("//name");
        for (Node node : nodes) {
            Element element = (Element) node;
            System.out.println(element.getText());
        }
    }
}

结果为:

Dom4J配合XPath解析schema约束的xml配置文件问题

我们会发现,同样的代码,运行在引入了Schema约束的xml文件上虽然正常运行了,但是并没有达到我们想要的结果,document对象获取到的nodes集合是个空集合[]

产生问题的原因

当XPath表达式中没有前缀时,查询的元素命名空间也应该是默认值,否则是查询不到结果的。引入了Schema约束的xml文件使用了命名空间,此时查询元素的命名空间不再是默认值了,所以此时的结果是个空集合。

解决方案:

此时如果想要正确的解析结果,必须设置命名空间后再对文档进行解析。

修改后的测试类:

public class DemoBook {
    public static void main(String[] args) throws DocumentException {
        SAXReader reader = new SAXReader();
        //声明一个map集合保存命名空间
        Map<String,String > map = new HashMap<>();
        //给命名空间取别名
        map.put("myNameSpace","http://www.mytest.com/book");
        //设置命名空间
        reader.getDocumentFactory().setXPathNamespaceURIs(map);
        //读取文档
        Document document = reader.read(Demo1.class.getResourceAsStream("book.xml"));
        List<Node> nodes = document.selectNodes("//myNameSpace:name");
        for (Node node : nodes) {
            Element element = (Element)node;
            System.out.println(element.getText());
        }
    }
}

运行结果:
Dom4J配合XPath解析schema约束的xml配置文件问题

Perfect~


相关文章

  • 目录 引入 简单工厂 抽象工厂 Spring的bean工厂 模拟Spring工厂实现 模拟IOC 引入 假设有一个司机, 需要到某个城市, 于是我们给他一辆汽车 public class Demo { public static void ...
  • 前言:今天在做一个小项目时,客户要求的xml,跟现在有系统要求的不一样,所以要自己重新写函数支持返回,进行简单总结,希望对大家有所帮助. 首先,使用xml函数需要链上动态库libxml2,需要在电脑上安装libxml的开发包,安装方法如下: ...
  • SpringBoot集成Lombok,应用+源码解析,让代码优雅起来
    一.Lombok简介 (1)Lombok官网(https://projectlombok.org/)对lombok的介绍 (2)GitHub项目地址:https://github.com/rzwitserloot/lombok 虽然是生硬的 ...
  • 学了很多乱七杂八的东西,但是依然停留在前端,在工作中一直和后端交流,但是不太了解数据库是怎么回事,为了加强学习,准备学习一些关于数据库相关的东西. 说起数据库可能会有很多很多,SQLServer.Oracle.Sybase等等等,还有就是要 ...
  • 为什么说 Java 程序员到了必须掌握 Spring Boot 的时候?
    Spring Boot 2.0 的推出又激起了一阵学习 Spring Boot 热,就单从我个人的博客的访问量大幅增加就可以感受到大家对学习 Spring Boot 的热情,那么在这么多人热衷于学习 Spring Boot 之时,我自己也在 ...

2020 cecdns.com webmaster#cecdns.com
12 q. 0.045 s.
京ICP备10005923号