【问题标题】:How can I specify JAXB customizations externally to a WSDL file?如何在 WSDL 文件外部指定 JAXB 自定义?
【发布时间】:2013-09-13 14:54:55
【问题描述】:

我有一个用 .NET 实现的服务的 WSDL 文件。我也有相同的文件,其中包含由第 3 方制作的一些“自定义”,以使该文件可以容忍wsimport,主要是以下形式:

<s:annotation>
  <s:appinfo>
    <jaxb:property name="result"/>
  </s:appinfo>
</s:annotation>

我希望能够处理来自供应商的原始 WSDL 以及这些覆盖,但我希望在外部指定它们。我看到我可以将wsimport 的-b 选项用于“绑定文件”,并且我尝试编写一个当前看起来像这样的覆盖文件:

<jxb:bindings version="1.0"
  xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
  xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <jxb:bindings node="//xs:element[@name='MyElementResult']">
    <jxb:property name="result"/>
  </jxb:bindings>
</jxb:bindings>

我已验证“MyElementName”确实存在,在此处找到的元素中:

<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions
     xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
     xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/"
     xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
     xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
     xmlns:tns="vendor-uri"
     xmlns:s="http://www.w3.org/2001/XMLSchema"
     xmlns:s2="http://microsoft.com/wsdl/types/"
     xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
     xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
     targetNamespace="vendor-namespace"
     xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">

  [...]
  <s:element name="MyElementResponse">
    <s:complexType>
      <s:sequence>
        <s:element minOccurs="0" maxOccurs="1" name="MyElementResult" type="tns:Result" />

我收到了来自wsimport 的警告(因此没有任何变化):

[ERROR] XPath evaluation of "//xs:element[@name='MyElementResult']" results in empty target node
  line 4 of file:/Users/..../wsdl/custom-bindings.xjb

我的声明中是否遗漏了什么?我的 XPath 表达式不正确吗?如果我的 XPath/覆盖工作正常,它的格式是否正确以便获得与编辑原始 WSDL 相同的结果?

这甚至可以使用外部文件,还是我必须用这些相同的更改重新修改任何未来版本的 WSDL?

【问题讨论】:

  • 如果您在覆盖文件中使用与原始 WSDL 文件中名称空间 http://www.w3.org/2001/XMLSchema 相同的名称空间别名 s,而不是您拥有的别名 xs,是否会有所不同?上面?
  • 不:当我在选择器中使用xmlns:s 然后//s:element 时,我得到了同样的错误。我有点希望wsimport 只是愚蠢的,这将是解决方案,但幸运的是wsimport 似乎可以正确处理XML,并且当两个不同的文档使用不同的命名空间名称时不用担心(这是命名空间的全部意义)。
  • 如果您更改 XPath 表达式,您会得到任何不同的结果吗?例如,指定绝对路径、不同但足够等效的匹配条件等。
  • 看起来没有:我将 XPath 更改为简单的 //s:element 并得到相同的错误:[ERROR] XPath evaluation of "//s:element" results in empty target node
  • 我在想也许我应该自己使用 XSLT 预处理 WSDL,而不是依靠 wsimport 为我做这件事。

标签: jaxb wsdl jax-ws wsimport


【解决方案1】:

您需要在绑定 XML 文件中提供架构位置。

<jxb:bindings version="1.0"
     xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
     xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <jxb:bindings 
         schemaLocation="PATH_TO_YOUR_WSDL#types?schema1"
         node="//xs:schema[@targetNamespace='SCHEMA_NAMESPACE']">
        <jxb:bindings node="//xs:element[@name='MyElementResult']">
            <jxb:property name="result"/>
        </jxb:bindings>
    </jxb:bindings>
</jxb:bindings>

WSDL 文件名后面的#types?schema1 将指定您要绑定的 WSDL 中的哪个模式,从 1 开始。

【讨论】:

  • 这似乎不能解决问题,但我可能做错了。如果我的 WSDL 文件名为 foo.wsdl,我是直接使用 &lt;jxb:bindings schemaLocation="foo.wsdl#types?schema1"&gt; 还是比这更细微? (等等...... WSDL 文件中有多个模式......也许我必须重复所有这些东西......)。
  • 我在示例中添加了以下内容:node="//xs:schema[@targetNamespace='SCHEMA_NAMESPACE']"。确保您提供的 SCHEMA_NAMESPACE 值与您尝试选择的架构上的 targetNamespace 属性相匹配。
  • 我在这里取得了进展。 2年后才回到这个状态需要一些时间:)
  • 只需 作为您的第一个绑定节点就足够了。
猜你喜欢
  • 2014-10-30
  • 2011-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多