关于Java:如何从标记中删除名称空间,但保留其前缀?

How to remove namespace from a tag but leave its prefix?

我能够生成SOAP消息,但我不知道

  • 仅将前缀添加到soapMessage标记(不应具有名称空间)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
     SOAPConnectionFactory soapConnectionFactory =
                    SOAPConnectionFactory.newInstance();
     SOAPConnection connection =
                    soapConnectionFactory.createConnection();
     SOAPFactory soapFactory =
                    SOAPFactory.newInstance();

     MessageFactory factory =
                    MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);

     SOAPMessage message = factory.createMessage();
     SOAPHeader header = message.getSOAPHeader();
     SOAPPart soapPart = message.getSOAPPart();
     SOAPEnvelope soapEnvelope = soapPart.getEnvelope();                
     SOAPBody body = soapEnvelope.getBody();

     soapEnvelope.removeNamespaceDeclaration(soapEnvelope.getPrefix());
     soapEnvelope.setPrefix("soap");
     body.setPrefix("soap");

     header.removeNamespaceDeclaration(header.getPrefix());
     header.setPrefix("soap");

     soapEnvelope.addNamespaceDeclaration("v9","URL TO SERVER");

     Name bodyName;
     bodyName = soapFactory.createName("SearchHotels");
     SOAPBodyElement getList = body.addBodyElement(bodyName);
     getList.setPrefix("v9");

     Name childName = soapFactory.createName("SoapMessage","v9","URL TO SERVER");
     SOAPElement HotelListRequest = getList.addChildElement(childName);

     HotelListRequest.addChildElement("Hotel","v9").addTextNode("Hilton");

我的SOAP消息

1
2
3
   ...
     <v9:SoapMessage xmlns:els="URL TO SERVER">
         ...

我期望的是

1
2
3
   ...
      <v9:SoapMessage>
           ...

更新:

如果我使用以下命令,则会遇到以下错误

1
2
3
4
    SOAPElement HotelListRequest = getList.addChildElement("v9:SoapMessage");

    org.w3c.dom.DOMException: NAMESPACE_ERR: An attempt is made to create or change an object in a
                                             way which is incorrect with regard to namespaces.


要将名称空间前缀添加到所有标签,必须在每个插入的子代上重新声明所需的前缀(并最终声明名称空间),否则它将从父元素继承(隐式)名称空间。

例如尝试:

1
SOAPBodyElement getList = body.addBodyElement(bodyName,"v9","http://URL TO SERVER");

1
soapBody.addChildElement("SomeElement","v9","http://URL TO SERVER");

1
soapBody.addChildElement("v9:SomeElement");

有时您可能必须使用QName对象,而不仅仅是StringName

这在很大程度上取决于您使用的SOAP-API /实现,但是原理在所有地方都是相同的:重新声明(显式)或继承(隐式)。


在您期望的SOAP消息中,前缀的情况有所不同,似乎您正在编写客户端请求向.net中开发的服务提供商的请求,这就是为什么您可能需要更改前缀的原因。

我认为您可以从以下代码中了解概念:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
       MessageFactory messageFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);
    SOAPMessage soapMessage = messageFactory.createMessage();

    SOAPPart soapPart = soapMessage.getSOAPPart();

    SOAPEnvelope soapEnvelope = soapPart.getEnvelope();

    SOAPBody soapBody = soapEnvelope.getBody();

    soapEnvelope.removeNamespaceDeclaration(soapEnvelope.getPrefix());
    soapEnvelope.addNamespaceDeclaration("soap","http://schemas.xmlsoap.org/soap/envelope/");

    soapEnvelope.setPrefix("soap");
    soapBody.setPrefix("soap");

    soapEnvelope.addNamespaceDeclaration("xsi","http://www.w3.org/2001/XMLSchema-instance");
    soapEnvelope.addNamespaceDeclaration("xsd","http://www.w3.org/2001/XMLSchema");   soapMessage.getSOAPHeader().detachNode();

    soapMessage.getMimeHeaders().setHeader("SOAPAction","http://www.example.com/TransactionProcess");

有关更多详细信息,请访问此参考链接