无法使用XPath获取XML的节点值

时间:2017-04-05 12:48:33

标签: java xml xpath

我的XML如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope`enter code here`
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soapenv:Header>
        <platformMsgs:documentInfo
            xmlns:platformMsgs="urn:messages_2015_1.platform.webservices.netsuite.com">
            <platformMsgs:nsId>WEBSERVICES_3479023</platformMsgs:nsId>
        </platformMsgs:documentInfo>
    </soapenv:Header>
    <soapenv:Body>
        <addListResponse
            xmlns="">
            <platformMsgs:writeResponseList
                xmlns:platformMsgs="urn:messages_2015_1.platform.webservices.netsuite.com">
                <platformCore:status isSuccess="true"
                    xmlns:platformCore="urn:core_2015_1.platform.webservices.netsuite.com"/>
                    <platformMsgs:writeResponse>
                        <platformCore:status isSuccess="false"
                            xmlns:platformCore="urn:core_2015_1.platform.webservices.netsuite.com">
                            <platformCore:statusDetail type="ERROR">
                                <platformCore:code>DUP_ENTITY</platformCore:code>
                                <platformCore:message>This entity already exists.</platformCore:message>
                            </platformCore:statusDetail>
                        </platformCore:status>
                    </platformMsgs:writeResponse>
                </platformMsgs:writeResponseList>
            </addListResponse>
        </soapenv:Body>
    </soapenv:Envelope>

为了使用XPath获取价值,我编写了以下类:

package com.scholastic.intl.esb.integration.resource;

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

import javax.xml.namespace.NamespaceContext;

public class SimpleNamespaceContext implements NamespaceContext {

    private final Map<String, String> PREF_MAP = new HashMap<String, String>();

    public SimpleNamespaceContext(final Map<String, String> prefMap) {
        PREF_MAP.putAll(prefMap);       
    }

    public String getNamespaceURI(String prefix) {
        return PREF_MAP.get(prefix);
    }

    public String getPrefix(String uri) {
        throw new UnsupportedOperationException();
    }

    public Iterator getPrefixes(String uri) {
        throw new UnsupportedOperationException();
    }

}

以下代码应该读取platformCore的值:message:

String xPathStr = "/soapenv:Envelope/soapenv:Body/addListResponse/platformMsgs:writeResponseList/platformCore:status/platformMsgs:writeResponse/platformCore:status/platformCore:statusDetail/platformCore:message";

XPath xPath = XPathFactory.newInstance().newXPath();
            Map<String, String> prefMap = new HashMap<String, String>() {{
                put("soapenv", "http://schemas.xmlsoap.org/soap/envelope/");
                put("xsd", "http://www.w3.org/2001/XMLSchema");
                put("xsi", "http://www.w3.org/2001/XMLSchema-instance");
                put("platformMsgs", "urn:messages_2015_1.platform.webservices.netsuite.com");
                put("platformCore", "urn:core_2015_1.platform.webservices.netsuite.com");
            }};
            xPath.setNamespaceContext(new SimpleNamespaceContext(prefMap));
            System.out.println("Expression value: "+xPath.evaluate(xPathStr, new InputSource(new StringReader(netSuiteResponse))));

其中netSuiteResponse是SOAP格式的输入SOAP消息,但在Sysout语句中没有打印任何值。

请告诉我这里出了什么问题以及如何正确地做到这一点。

此致 Anirban。

1 个答案:

答案 0 :(得分:0)

你不能像这样处理空的namspace,你可以匹配名称。

    String xPathStr = "/soapenv:Envelope/soapenv:Body/*[name()='addListResponse']"
            + "/platformMsgs:writeResponseList"
            + "/platformCore:status/@isSuccess"
            // + "/platformMsgs:writeResponse/platformCore:status/platformCore:statusDetail/platformCore:message";
            ;
    String xPathStr2 = "/soapenv:Envelope/soapenv:Body/*[name()='addListResponse']"
            + "/platformMsgs:writeResponseList"
            + "/platformMsgs:writeResponse"
            + "/platformCore:status"
            + "/platformCore:statusDetail"
            + "/platformCore:message";
            ;
    XPath xPath = XPathFactory.newInstance().newXPath();
    Map<String, String> prefMap = new HashMap<String, String>() {
        {
            put("soapenv", "http://schemas.xmlsoap.org/soap/envelope/");
            put("xsd", "http://www.w3.org/2001/XMLSchema");
            put("xsi", "http://www.w3.org/2001/XMLSchema-instance");
            put("platformMsgs", "urn:messages_2015_1.platform.webservices.netsuite.com");
            put("platformCore", "urn:core_2015_1.platform.webservices.netsuite.com");
        }
    };
    xPath.setNamespaceContext(new SimpleNamespaceContext(prefMap));
    System.out.println(
            "Expression value: " + xPath.evaluate(xPathStr, new InputSource(new StringReader(example))));
    System.out.println(
            "Expression value: " + xPath.evaluate(xPathStr2, new InputSource(new StringReader(example))));

将导致:

Expression value: true
Expression value: This entity already exists.