[英]How to remove prefix and namespace in SOAPElement?
同事,我有創建具有必要結構的肥皂 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("");
}
}
}
結果我收到了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>
我的問題是如何從<in>
元素中僅刪除xmlns="http://mayacomp/Generic/Ws"
並接收:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<ns3:request xmlns:ns3="http://mayacomp/Generic/Ws">
<in>
<requestHeader>
更新
我試圖配置 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
但它對'in'元素沒有影響。 運行后我仍然有: <in xmlns="http://mayacomp/Generic/Ws">
更新
我通過調用 ws 解決了這個問題:
getWebServiceTemplate().marshalSendAndReceive(
"URL",
request,
new WebServiceMessageCallback()
{ public void doWithMessage(WebServiceMessage message) {
SaajSoapMessage saajSoapMessage = (SaajSoapMessage)message;
SOAPMessage soapMessage = UtilsClass.createSOAPMessage(in);
saajSoapMessage.setSaajMessage(soapMessage);
}
}
);
方法createSOAPMessage使用javax.xml.soap 庫配置soap 消息。
您可以使用類似的方法刪除該屬性
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");
}
以下測試表明它確實有效。
@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());
}
輸出是
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>
如果我正確理解了這個問題,您的代碼將獲得以下 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>
並且您希望將其轉換為以下 XML:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<ns3:request xmlns:ns3="http://mayacomp/Generic/Ws">
<in>
<requestHeader>
在這種情況下,調整命名空間聲明和命名空間前綴是不夠的,因為在 DOM 中, in
和requestHeader
元素仍將位於http://mayacomp/Generic/Ws
命名空間中。 這是因為 DOM 元素的命名空間 URI 是在創建/解析時確定的,並且在以后添加或刪除命名空間聲明時不會改變。 當 DOM 被序列化時,序列化器將自動生成必要的命名空間聲明,以確保輸出中的元素有效地具有它們在 DOM 中的命名空間。 這就是您在輸出中得到xmlns="http://mayacomp/Generic/Ws"
的原因,盡管 DOM 中不存在該名稱空間聲明。
您真正需要做的是更改這些元素的名稱空間 URI。 不幸的是,DOM 節點沒有setNamespaceURI
方法,您需要改用Document.renameNode
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.