java - 如何删除 SOAPElement 中的前缀和命名空间?

标签 java xml dom wsdl saaj

同事们,我有一个循环,它创建了具有必要结构的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("");
        }
    }
}

结果我收到了 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>

我的问题是如何只删除 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>

更新

我尝试配置 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 消息。

最佳答案

如果我正确理解问题,您的代码将获得以下 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 中,inrequestHeader 元素仍将位于 http 中://mayacomp/Generic/Ws 命名空间。这是因为 DOM 元素的 namespace URI 是在创建/解析时确定的,并且在以后添加或删除 namespace 声明时不会更改。当 DOM 被序列化时,序列化程序将自动生成必要的命名空间声明,以确保输出中的元素有效地具有它们在 DOM 中的命名空间。这就是为什么您在输出中得到 xmlns="http://mayacomp/Generic/Ws",尽管 DOM 中不存在该命名空间声明。

您真正需要做的是更改这些元素的 namespace URI。不幸的是,DOM 节点没有 setNamespaceURI 方法,您需要改用 Document.renameNode

关于java - 如何删除 SOAPElement 中的前缀和命名空间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33919701/

相关文章:

java - Put 请求上的 HTTP 403 Forbidden Jersey

c# - XslCompiledTransform 使用 UTF-16 编码

javascript - 是否可以使用函数设置 DefaultCheck? react

java - 在 Sax 解析器 (XML) 中处理外部实体和样式表

xml - 描述和内容的区别 :encoded tags in RSS2

javascript - 按类获取元素内的元素 - JavaScript

javascript - 使用 jQuery 获取 DOM 元素的 XPath

java - 用 Java 填充 HUD

java - SQLiteDatabase rawQuery() 中的 StringIndexOutOfBoundsException

java - 为什么有人会像这样构造一个 while 循环?