dom4j解析含有命名空间的XML

XML 复制代码
<soap:Envelope
    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Body>
        <s4000CfmTransferResponse
            xmlns="http://service.ccbs.test.com/">
            <return>
                <ROOT>
                    <OUT_DATA>
                        <USER_INFO>
                            <PHONE_NO>1</PHONE_NO>
                            <STAND_ADDRESS>2</STAND_ADDRESS>
                            <ITEL_ACCOUNT>3</ITEL_ACCOUNT>
                            <SVC_ID>4</SVC_ID>
                            <SVC_NAME>5</SVC_NAME>
                            <PROD_ID>6</PROD_ID>
                            <IPTV_ACCOUNT>7</IPTV_ACCOUNT>
                        </USER_INFO>
                        <USER_INFO>
                            <PHONE_NO>8</PHONE_NO>
                            <STAND_ADDRESS>9</STAND_ADDRESS>
                            <ITEL_ACCOUNT>10</ITEL_ACCOUNT>
                            <SVC_ID>11</SVC_ID>
                            <SVC_NAME>12</SVC_NAME>
                            <PROD_ID>13</PROD_ID>
                            <IPTV_ACCOUNT>14</IPTV_ACCOUNT>
                        </USER_INFO>
                        <USER_INFO>
                            <PHONE_NO>15</PHONE_NO>
                            <STAND_ADDRESS>16</STAND_ADDRESS>
                            <ITEL_ACCOUNT>17</ITEL_ACCOUNT>
                            <SVC_ID>18</SVC_ID>
                            <SVC_NAME>19</SVC_NAME>
                            <PROD_ID>20</PROD_ID>
                            <IPTV_ACCOUNT>21</IPTV_ACCOUNT>
                        </USER_INFO>
                    </OUT_DATA>
                    <RETURN_MSG>OK</RETURN_MSG>
                    <PROMPT_MSG/>
                    <RETURN_CODE>0</RETURN_CODE>
                    <USER_MSG>OK</USER_MSG>
                    <DETAIL_MSG>OK</DETAIL_MSG>
                    <RUN_IP>xxx</RUN_IP>
                </ROOT>
            </return>
        </s4000CfmTransferResponse>
    </soap:Body>
</soap:Envelope>

1、未处理名称空间返回为空

java 复制代码
        //解析xml
        Document document = DocumentHelper.parseText(xml);
        Element root = document.getRootElement();

        //0代表成功
        String retCode = root.selectSingleNode("//ROOT/RETURN_CODE").getText().trim();
        List<Object> list = new ArrayList<>();
        if ("0".equals(retCode)) {
            List<Node> nodes = root.selectNodes("//ROOT/OUT_DATA/USER_INFO");
            for (Node node : nodes) {
                String PHONE_NO = node.selectSingleNode("PHONE_NO").getText();
                String STAND_ADDRESS = node.selectSingleNode("STAND_ADDRESS").getText();
                HashMap<String, Object> map = new HashMap<>();
                map.put("PHONE_NO", PHONE_NO);
                map.put("STAND_ADDRESS", STAND_ADDRESS);
                list.add(map);
            }
        }

2、处理xml的名称空间,已经能正常获取值了。这一步是测试,就是没有标签没有前缀,但是需要得到没有前缀默认的名称空间

java 复制代码
        //解析xml
        Document document = DocumentHelper.parseText(xml);
        Element root = document.getRootElement();

        // 添加命名空间,作用域在整个文档
        Map<String, String> xmlMap = new HashMap<>();
        // 因为有2个命名空间属性,所以添加2个
        xmlMap.put("soap", "http://schemas.xmlsoap.org/soap/envelope/");
        xmlMap.put("xmlns", "http://service.ccbs.test.com/");


        XPath xpath = document.createXPath("//soap:Envelope/soap:Body");
        xpath.setNamespaceURIs(xmlMap);
        // 获取第二层xml的命名空间,因为s4000CfmTransferResponse没有名称空间,我需要看默认s4000CfmTransferResponse的名称空间
        String secendUrl = ((Element) xpath.selectSingleNode(document)).element("s4000CfmTransferResponse").getNamespaceURI();
        System.out.println("默认的名称空间:" + secendUrl);

        xpath = document.createXPath("//soap:Envelope/soap:Body/xmlns:s4000CfmTransferResponse");
        xpath.setNamespaceURIs(xmlMap);
        Node node2 = xpath.selectSingleNode(document);


        xpath = document.createXPath("//xmlns:ROOT/xmlns:OUT_DATA/xmlns:USER_INFO");
        xpath.setNamespaceURIs(xmlMap);
        List<Node> node3 = xpath.selectNodes(document);

如果不知道标签的名称空间是什么,可以用下面的方法打印xml所有标签的名称空间

java 复制代码
    /**
     * 打印名称空间
     */
    public static void outNamespace(String xml) throws DocumentException {
        // xml必须有一个根节点
        xml = "<root>" + xml + "</root>";
        Document document = DocumentHelper.parseText(xml);
        Element root = document.getRootElement(); //根节点
        outNamespace(root);
    }

    /**
     * 打印名称空间
     */
    private static void outNamespace(Element element) {
        List<Element> list = element.elements(); //获取所有子节点
        for (Element iter : list) { //遍历所有子节点
            if (iter.elements().size() > 0) { //子节点还有子节点
                outNamespace(iter); //递归调用
                String name = iter.getName();//标签名称
                String namespaceURI = iter.getNamespaceURI();//名称空间
                System.out.println(name + "=" + namespaceURI);
            } else { //子节点无子节点
                String name = iter.getName();//标签名称
                String namespaceURI = iter.getNamespaceURI();//名称空间
                System.out.println(name + "=" + namespaceURI);
            }
        }
    }

3、最后正常的处理方式如下:

XML 复制代码
        //解析xml
        Document document = DocumentHelper.parseText(xml);
        Element root = document.getRootElement();
        // 添加命名空间
        Map<String, String> xmlMap = new HashMap<>();
        // 因为有2个命名空间属性,所以添加2个
        xmlMap.put("soap", "http://schemas.xmlsoap.org/soap/envelope/");
        xmlMap.put("xmlns", "http://service.ccbs.test.com/");
        //XPath解析,带名称空间
        XPath xpath = document.createXPath("//xmlns:ROOT/xmlns:RETURN_CODE");
        xpath.setNamespaceURIs(xmlMap);

        //0代表成功
        String retCode = xpath.selectSingleNode(document).getText().trim();
        List<Object> list = new ArrayList<>();
        if ("0".equals(retCode)) {
            xpath = document.createXPath("//xmlns:ROOT/xmlns:OUT_DATA/xmlns:USER_INFO");
            xpath.setNamespaceURIs(xmlMap);
            List<Node> nodes = xpath.selectNodes(document);
            for (Node node : nodes) {
                String PHONE_NO = ((Element) node).element("PHONE_NO").getText();
                String STAND_ADDRESS = ((Element) node).element("STAND_ADDRESS").getText();
                HashMap<String, Object> map = new HashMap<>();
                map.put("PHONE_NO", PHONE_NO);
                map.put("STAND_ADDRESS", STAND_ADDRESS);
                list.add(map);
            }
        }
相关推荐
武子康1 天前
Java-39 深入浅出 Spring - AOP切面增强 核心概念 通知类型 XML+注解方式 附代码
xml·java·大数据·开发语言·后端·spring
Ll13045252983 天前
基于 COM 的 XML 解析技术(MSXML) 的总结
xml
在代码的海洋中寻找亚特兰蒂斯3 天前
AJAX对于XML和JSON的处理
xml·ajax·json
BinField4 天前
ToolsSet之:XML工具
xml·windows·microsoft
SEO-狼术5 天前
Connect Directly to Oracle XML Data
xml·数据库·oracle
YSoup5 天前
2025年目前最新版本Android Studio自定义xml预览的屏幕分辨率
android·xml·android studio
abcnull6 天前
mybatis的mapper对应的xml写法
xml·sql·spring·mybatis·mapper
Blue桃之夭夭6 天前
HTML、XML、JSON 是什么?有什么区别?又是做什么的?
xml·html·json
小于村6 天前
pom.xml 文件中配置你项目中的外部 jar 包打包方式
xml·java·jar
扶风呀6 天前
pom.xml中标签详解_
xml