在搜查过程中的XPath返回null(During the search xPath returns

2019-10-30 10:48发布

我有这个wsdl文件

<definitions targetNamespace="http://testwork/" name="HelloWorldService"
             xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
             xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsp1_2="http://schemas.xmlsoap.org/ws/2004/09/policy"
             xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata"
             xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
             xmlns:tns="http://testwork/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
             xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
    <types>
        <xsd:schema>
            <xsd:import namespace="http://soapServlet/" schemaLocation="http://localhost:8085/testwork/soapServlet?xsd=1"/>
        </xsd:schema>
    </types>
    <message name="sayHelloWorldFrom">
        <part name="parameters" element="tns:sayHelloWorldFrom"/>
    </message>
    <message name="sayHelloWorldFromResponse">
        <part name="parameters" element="tns:sayHelloWorldFromResponse"/>
    </message>
    <message name="additionalFault">
        <wsdl:part name="error" element="tns:responseFault"/>
    </message>
    <portType name="HelloWorld">
        <operation name="sayHelloWorldFrom">
            <input wsam:Action="http://testwork/HelloWorld/sayHelloWorldFromRequest" message="tns:sayHelloWorldFrom"/>
            <output wsam:Action="http://testwork/HelloWorld/sayHelloWorldFromResponse" message="tns:sayHelloWorldFromResponse"/>
            <wsdl:fault name="error" message="additionalFault"/>
        </operation>
    </portType>
    <binding name="HelloWorldPortBinding" type="tns:HelloWorld">
        <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
        <operation name="sayHelloWorldFrom">
            <soap:operation soapAction=""/>
            <input>
                <soap:body use="literal"/>
            </input>
            <output>
                <soap:body use="literal"/>
            </output>
            <fault name="error">
                <soap:fault name="error" use="literal"/>
            </fault>
        </operation>
    </binding>
    <service name="HelloWorldService">
        <port name="HelloWorldPort" binding="tns:HelloWorldPortBinding">
            <soap:address location="http://localhost:8085/testwork/soapServlet"/>
        </port>
    </service>
</definitions>

我使用XPath搜索操作名称,这是我的代码片段

public void parseWsdl(String wsdl, String funcName) throws ServiceException {
        InputStream isr = IOUtils.toInputStream(wsdl);
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true);
        funcName = "sayHelloWorldFrom";
        try {
            org.w3c.dom.Document doc = factory.newDocumentBuilder().parse(isr);
            XPathFactory xFactory = XPathFactory.newInstance();
            XPath xPath = xFactory.newXPath();
            xPath.setNamespaceContext(new MyNamespaceContext());
            org.w3c.dom.Element element = (org.w3c.dom.Element) xPath.compile("ns:definitions/ns:portType/ns:operation[@name='" + funcName +"']").evaluate(doc, XPathConstants.NODE);
            log.info("element " + element);
            if (element == null) {
                throw new ServiceException(ErrorCode.SOAP_EXCEPTION_005);
            }
        } catch (ParserConfigurationException e) {
            throw new ServiceException(e, ErrorCode.SOAP_EXCEPTION_002);
        } catch (XPathExpressionException e) {
            throw new ServiceException(e, ErrorCode.SOAP_EXCEPTION_006);
        } catch (SAXException e) {
            throw new ServiceException(e, ErrorCode.SOAP_EXCEPTION_002);
        } catch (IOException e) {
            throw new ServiceException(e, ErrorCode.SOAP_EXCEPTION_001);
        }
    }


import javax.xml.namespace.NamespaceContext;
import java.util.Iterator;

public class MyNamespaceContext implements NamespaceContext {

    public String getNamespaceURI(String prefix) {
        if("ns".equals(prefix)) {
            return "http://schemas.xmlsoap.org/wsdl/";
        }
        return null;
    }

    public String getPrefix(String namespaceURI) {
        return null;
    }

    public Iterator getPrefixes(String namespaceURI) {
        return null;
    }

}

但是,即使操作名称是“sayHelloWorldFrom”,元素仍是零,什么是错的? 我认为这个问题是在默认的命名空间,但我试图解决这个问题,上述类的帮助,但没有解决问题。

Answer 1:

你可以尝试tns命名空间?

org.w3c.dom.Element element = (org.w3c.dom.Element) xPath.compile("tns:definitions/tns:portType/tns:operation[@name='" + funcName +"']").evaluate(doc, XPathConstants.NODE);

编辑:

我查了许多选项来解决此问题。 首先,我改变了前缀名wsdl ,因为它是WSDL的命名空间。 但它没有帮助。 其次,我检查了您的WSDL。 这是奇怪的,我的WSDL的命名空间声明:

xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

当我第一次deledet我得到了正确的元素。 我测试的XPath测试仪。

我的XPath表达式:

//portType/operation[@name='sayHelloWorldFrom']

我的代码:

DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
domFactory.setNamespaceAware(true);
DocumentBuilder builder = domFactory.newDocumentBuilder();
Document doc = builder.parse(wsdl);

XPathFactory xFactory = XPathFactory.newInstance();
XPath xPath = xFactory.newXPath();
xPath.setNamespaceContext(new MyNamespaceContext());
XPathExpression expr = xPath.compile("//wsdl:portType/wsdl:operation[@name='" + funcName +"']");
org.w3c.dom.Element element = (org.w3c.dom.Element)expr.evaluate(doc, XPathConstants.NODE); 

现在,在这种情况下,当我添加portype没有名字的前缀,我得到空。 所以,我用前缀java代码。 请检查并测试一下吧!



文章来源: During the search xPath returns null