我有这个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”,元素仍然是null,有什么问题?我认为问题出在默认命名空间中,但我试图在上述类的帮助下解决这个问题,但问题没有解决。
答案 0 :(得分:0)
你可以试试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/"
当我首先删除时,我得到了正确的元素。我使用XPath Tester.
进行了测试我的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
而没有名称前缀时,我得到null。所以,我在java代码中使用前缀。请检查并测试它!