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

Posted story-xc

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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());
        }
    }
}

结果为:

技术图片

我们会发现,同样的代码,运行在引入了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());
        }
    }
}

运行结果:
技术图片

Perfect~

以上是关于Dom4J配合XPath解析schema约束的xml配置文件问题的主要内容,如果未能解决你的问题,请参考以下文章

Java xml 操作(Dom4J修改xml   + xPath技术  + SAX解析 + XML约束)

servlet执行

如何使用DOM4j+xpath 解析

XML&反射

200分求解:dom4j 使用XPATH解析。。诡异的问题

dom4j对xml解析