java 如何删除 SOAPElement 中的前缀和命名空间?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33919701/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to remove prefix and namespace in SOAPElement?
提问by May12
Collogues, i have cycle which create soap xml with nessesary structure (don't ask about the structure)
Collogues,我有一个循环创建具有必要结构的soap xml(不要询问结构)
log.info("Body elements: ");
NodeList nodeList = body.getElementsByTagName("*") ;
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE) {
log.info(node.getNodeName());
if (node.getNodeName().equals("ns2:request")) {
log.info("Set namespace and prefix for " + node.getNodeName());
SOAPElement childX = (SOAPElement) node;
childX.removeNamespaceDeclaration(childX.getPrefix()) ;
childX.addNamespaceDeclaration("ns3", "http://mayacomp/Generic/Ws");
childX.setPrefix("ns3");
}
else {
if (node.getNodeName().equals("ns2:in") ) {
log.info("Remove namespace for " + node.getNodeName());
SOAPElement childX = (SOAPElement) node;
childX.removeNamespaceDeclaration(childX.getPrefix()) ;
childX.addNamespaceDeclaration("", "");
childX.setPrefix("");
}
SOAPElement childX = (SOAPElement) node;
childX.removeNamespaceDeclaration(childX.getPrefix()) ;
childX.setPrefix("");
}
}
}
As a result I receive xml:
结果我收到了 xml:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<ns3:request xmlns:ns3="http://mayacomp/Generic/Ws">
<in xmlns="http://mayacomp/Generic/Ws">
<requestHeader>
My question is how to remove only xmlns="http://mayacomp/Generic/Ws"
from <in>
element and receive:
我的问题是如何只删除xmlns="http://mayacomp/Generic/Ws"
从 <in>
元素和接收:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<ns3:request xmlns:ns3="http://mayacomp/Generic/Ws">
<in>
<requestHeader>
UPDATE
更新
I tried to config xml element:
我试图配置 xml 元素:
/*Config body elements*/
while (itBodyElements.hasNext())
{
Object o = itBodyElements.next();
SOAPBodyElement bodyElement = (SOAPBodyElement) o;
log.info("Elements from 'Body' element = " + bodyElement.getLocalName() );
Iterator it2 = bodyElement.getChildElements();
while (it2.hasNext())
{
Object requestElement = it2.next();
SOAPBodyElement bodyRequest = (SOAPBodyElement) requestElement;
log.info(" Elements from '"+ bodyElement.getLocalName() + "' element = " + bodyRequest.getLocalName());
log.info(" Delete namespace from IN element " + bodyRequest.getLocalName());
bodyRequest.removeNamespaceDeclaration(bodyRequest.getPrefix());
bodyRequest.setPrefix("");
Iterator it3 = bodyRequest.getChildElements();
while (it3.hasNext())
{ //work with other elements
But it has not effect to 'in' element. After run i still have:
<in xmlns="http://mayacomp/Generic/Ws">
但它对'in'元素没有影响。运行后我仍然有:
<in xmlns="http://mayacomp/Generic/Ws">
UPDATE
更新
I solved the problem by calling ws as next:
我通过调用 ws 解决了这个问题:
getWebServiceTemplate().marshalSendAndReceive(
"URL",
request,
new WebServiceMessageCallback()
{ public void doWithMessage(WebServiceMessage message) {
SaajSoapMessage saajSoapMessage = (SaajSoapMessage)message;
SOAPMessage soapMessage = UtilsClass.createSOAPMessage(in);
saajSoapMessage.setSaajMessage(soapMessage);
}
}
);
Method createSOAPMessageconfigure soap message using javax.xml.soap library.
方法createSOAPMessage使用 javax.xml.soap 库配置肥皂消息。
回答by Andreas Veithen
If I understand the question correctly, your code gets the following XML as input:
如果我正确理解了这个问题,您的代码将获得以下 XML 作为输入:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<ns2:request xmlns:ns3="http://mayacomp/Generic/Ws">
<ns2:in>
<ns2:requestHeader>
And you want to transform it into the following XML:
并且您想将其转换为以下 XML:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<ns3:request xmlns:ns3="http://mayacomp/Generic/Ws">
<in>
<requestHeader>
In this case, adjusting the namespace declarations and namespace prefixes is not enough because in the DOM the in
and requestHeader
elements will still be in the http://mayacomp/Generic/Ws
namespace. That is because the namespace URI of a DOM element is determined at creation/parse time and doesn't change when namespace declarations are added or removed later. When the DOM is serialized, the serializer will automatically generate the necessary namespace declarations to make sure that the elements in the output effectively have the namespaces they had in the DOM. That is why you get xmlns="http://mayacomp/Generic/Ws"
in the output, although that namespace declaration is not present in the DOM.
在这种情况下,调整命名空间声明和命名空间前缀是不够的,因为在 DOM 中,in
和requestHeader
元素仍将在http://mayacomp/Generic/Ws
命名空间中。这是因为 DOM 元素的命名空间 URI 在创建/解析时确定,并且在稍后添加或删除命名空间声明时不会更改。当 DOM 被序列化时,序列化器将自动生成必要的命名空间声明,以确保输出中的元素有效地拥有它们在 DOM 中的命名空间。这就是您进入xmlns="http://mayacomp/Generic/Ws"
输出的原因,尽管该命名空间声明不存在于 DOM 中。
What you really need to do is to change the namespace URI for these elements. Unfortunately, DOM nodes don't have a setNamespaceURI
method and you need to use Document.renameNode
instead.
您真正需要做的是更改这些元素的命名空间 URI。不幸的是,DOM 节点没有setNamespaceURI
方法,您需要使用它Document.renameNode
。
回答by Mike Murphy
You could just remove the attribute using something like
您可以使用类似的方法删除属性
XPath xPath = XPathFactory.newInstance().newXPath();
NodeList nList = (NodeList)xPath.evaluate("/Envelope/Body/request/in", body, XPathConstants.NODESET);
for (int i = 0; i < nList.getLength(); ++i) {
Element e = (Element) nList.item(i);
e.removeAttribute("xmlns");
}
The following test shows that it does work.
下面的测试表明它确实有效。
@Test
public void removeXmlns() throws Exception {
String xml = "" +
"<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\">\n" +
" <soapenv:Body>\n" +
" <ns3:request xmlns:ns3=\"http://mayacomp/Generic/Ws\">\n" +
" <in xmlns=\"http://mayacomp/Generic/Ws\">\n" +
" <requestHeader>\n" +
" </requestHeader>\n" +
" </in>\n" +
" </ns3:request>\n" +
" </soapenv:Body>\n" +
"</soapenv:Envelope>";
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(ResourceUtils.getFile("/soaptest.xml").getAbsolutePath());
Element body = document.getDocumentElement();
XPath xPath = XPathFactory.newInstance().newXPath();
NodeList nList = (NodeList)xPath.evaluate("/Envelope/Body/request/in", body, XPathConstants.NODESET);
for (int i = 0; i < nList.getLength(); ++i) {
Element e = (Element) nList.item(i);
e.removeAttribute("xmlns");
}
DOMSource domSource = new DOMSource(document);
StringWriter writer = new StringWriter();
StreamResult result = new StreamResult(writer);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.transform(domSource, result);
logger.info("XML IN String format is: \n" + writer.toString());
}
The output is
输出是
2015-11-26-11-46-24[]::[main]:(demo.TestCode.removeXmlns(TestCode.java:174):174):INFO :TestCode:XML IN String format is:
<?xml version="1.0" encoding="UTF-8" standalone="no"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<ns3:request xmlns:ns3="http://dfg/Ws">
<in>
<requestHeader>
</requestHeader>
</in>
</ns3:request>
</soapenv:Body>
</soapenv:Envelope>