Java:DOM4J解析带命名空间的XML

XML解析

在Java中,XML有多种方式可以解析.但用的比较多的还是DOM4J,对于带命名空间的XML解析,DOM4J官网并没有提供例子.下面的工厂类来自网络,我只是在其中增加了几个方法.另外,下面代码基于jdk1.8.

解析所使用的XML源文件:

<CDocument
    xmlns="urn:sc-wst:v2"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:sc-wst:v2 SD.xsd">
    <id root="1.1.2" extension="xxxxslkjfkls-fdsajkdfsklalk"></id>
    <code code="C0004" displayName="xiyao" codeSystem="WS/T 445-2014" codeSystemName="xxx"></code>
    <effectiveTime value="20170911164900"></effectiveTime>
    <patient>
        <sourceid value="68417800-1"></sourceid>
        <id root="1.35" extension="xxxxas"></id>
        <id root="1.19" extension="1eeqwww"></id>
        <id root="1.11" extension="11222321112"></id>
        <id root="1.20" extension="2334557765432"></id>
        <id root="1.13" extension="21245675432"></id>
        <addr use="B">
            <houseNumber></houseNumber>
            <streetName></streetName>
            <township></township>
            <county value="DPQDSF"></county>
            <city value="SWERS"></city>
            <state value="SCSSD"></state>
            <postalCode></postalCode>
        </addr>
        <addr use="H">
            <houseNumber></houseNumber>
            <streetName></streetName>
            <township></township>
            <county></county>
            <city></city>
            <state value="SCSSD"></state>
            <postalCode></postalCode>
        </addr>
        <addr use="P">
            <houseNumber></houseNumber>
            <streetName></streetName>
            <township></township>
            <county></county>
           <city value="SWERS"></city>
            <state value="SCSSD"></state>
            <postalCode></postalCode>
        </addr>
        <item xsi:type="ST" nid="HDSD00.04.014" name="EWRU" value="DSAF"></item>
        <item xsi:type="CD" nid="HDSD00.04.020" name="SEX" value="2" codeSystem="2.3.3.4"></item>
        <item xsi:type="PQ" nid="HDSD00.04.017" name="SDFDS" unit="FDSAFADS" value="2"></item>
        <item xsi:type="PQ" nid="HDSD00.04.018" name="DFSAF" unit="FDSA" value="9"></item>
        <item xsi:type="ST" nid="HDSD00.04.005" name="FSDAFSDFSAFSD" value="EKMZ"></item>
        <item xsi:type="CD" nid="HDSD00.04.029" name="DSAFDSAFASFDS" value="68417800-1" codeSystem="2.3.4.1"></item>
        <guardian use="FDSAFDSACZXCXZCXZ">
            <addr use="F">
                <houseNumber value="18"></houseNumber>
                <streetName value="fdsazds"></streetName>
                <township value="cxvzcx"></township>
                <county value="qwwrt"></county>
                <city value="cxvbcx"></city>
                <state value="vcioklx"></state>
                <postalCode value="610000"></postalCode>
            </addr>
        </guardian>
    </patient>
</CDocument>

java

源码

import org.dom4j.*;
import org.dom4j.io.SAXReader;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * DOM4J解析带命名空间的XML.
 *
 * Created by puruidong on 2017/9/15.
 */
public class Main {

    public static void main(String[] args) throws DocumentException {
        Dom4jFactory df = new Dom4jFactory("E:\\test.xml");
        df.getAllElement();
    }

}


/**
 * 解析工厂类.
 *
 * 来自网络.
 * 增加了几个方法.
 *
 */
class Dom4jFactory {
    private SAXReader reader = new SAXReader();
    private Document document;
    private static Element root;
    private static Map<String, String> xmlMap = new HashMap<>();

    public Dom4jFactory(String path) {
        super();
        try {
            document = reader.read(path);
            root = document.getRootElement();
            String defaultNamespace = root.getNamespaceURI();
            xmlMap.put("default", defaultNamespace);
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }

    /**
     * 递归获取节点数据.
     *
     *
     * @param elementList
     */
    public static void element(List<Element> elementList){
        if(elementList.size()==0){
            return ;
        }
        elementList.forEach(e->{
            List<Attribute> lists = e.attributes(); // 获取节点的属性.
            attribute(lists); // 遍历属性.
            element(e.elements()); // 递归调用.
        });
    }

    /**
     * 遍历属性数据.
     *
     *
     * @param attributes
     */
    public static void attribute(List<Attribute> attributes){
        attributes.forEach(x-> System.out.print(x.getQualifiedName()+"--"+":"+x.getName()+"--->"+x.getValue()+","));
        System.out.println("");
    }

    /**
     * 获取所有节点的值.
     *
     *
     * @throws DocumentException
     */
    public static void getAllElement() throws DocumentException {
        for (Iterator<Element> it = root.elementIterator(); it.hasNext();) {
            while(it.hasNext()){  // 循环获取根节点下面的节点.
                Element element = it.next(); // 获取节点.
                attribute(element.attributes()); // 获取本节点的属性.
                element(element.elements()); // 获取子节点(递归调用.)
            }
        }
    }

    /**
     * 获取指定节点.
     *
     *
     * @param arg0
     * @return
     */
    public static List<?> getSelectNodes(String arg0) {
        XPath selector = root.createXPath("//default:" + arg0);
        selector.setNamespaceURIs(xmlMap);
        return selector.selectNodes(root);
    }

    /**
     * 获取第一个节点.
     *
     * @param arg0
     * @param <T>
     * @return
     */
    public <T> T getSelectObject(String arg0){
        List<?> selectNodes = getSelectNodes(arg0);
        if(selectNodes.size()==1){
            return (T) selectNodes.get(0);
        }else{
            return null;
        }
    }
}