如何将命名空间声明从操作移动到根元素?

时间:2014-11-13 11:07:27

标签: java jaxb cxf

我们的肥皂信息如下所示:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
   <...>
</soap:Header>
<soap:Body>
    <ns2:operation xmlns="urn:namespace2" xmlns:ns2="urn:namespace1">
        <rootElement>
            <childElement>
                 <....>
            </childElement>
        </rootElement>
    </ns2:operation>
</soap:Body>

但我需要以下输出:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
 <...>
</soap:Header>
<soap:Body>
    <ns2:operation  xmlns:ns2="urn:namespace1">
        <rootElement xmlns="urn:namespace2">
            <childElement>
               <..>
            </childElement>
        </rootElement>
    </ns2:operation>
</soap:Body>

我使用了cxf中的wsdl2java来生成webservice / jaxb类。 是否可以更改jaxb的行为,以便在根元素中声明命名空间而不是在wsdl中定义的操作中?

我认为一种可能性是在发送之前使用CxfOutInterceptor来操作消息,但我认为必须有一个更容易/更快的解决方案。(例如,添加一个我不喜欢的简单注释知道生成的jaxb类。)

亲切的问候, soilworker

1 个答案:

答案 0 :(得分:1)

我在项目中所做的工作是将CXF XSLT Interceptor与以https://stackoverflow.com/a/16366984/5971497建模的样式表结合在一起

在您的情况下,您将使用ns2:operation而不是Accounts,但不要忘记在样式表元素中添加xmlns:ns2。

在我的情况下,客户端系统太笨拙,无法在从响应中提取子元素时将xmlns定义从父对象复制到子元素。

这是我的样式表:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:wst="http://docs.oasis-open.org/ws-sx/ws-trust/200512" xmlns:soap="http://www.w3.org/2003/05/soap-envelope" version="1.0">
  <xsl:output omit-xml-declaration="yes" indent="no"/>

  <!-- copy any unmatched nodes -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <!-- match any element with the wst prefix -->
  <xsl:template match="wst:*">
    <!-- create a new element with the same name as the matched one -->
    <xsl:element name="{name(.)}" namespace="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
      <!-- copy the xmlns attributes except for saml2 and ds, so they are declared on the Assertion element -->
      <xsl:copy-of select="./namespace::*[string(.)!='urn:oasis:names:tc:SAML:2.0:assertion' and string(.)!='http://www.w3.org/2000/09/xmldsig#']"/>
      <xsl:apply-templates />
    </xsl:element>
  </xsl:template>
</xsl:stylesheet>