自动从WSDL中将内联XSD提取到XSD文件中

Ste*_*ens 7 java xsd wsdl web-services

我正在使用第三方Web服务,其定义和实现是我无法控制的.此Web服务将来会发生变化.

应使用Web服务生成XML文件,该文件包含与Web服务相同的一些数据(由相同的XSD类型表示)以及程序生成的一些额外信息.

我的方法:

  1. 创建我自己的XSD,参考被调用的Web服务的WSDL的XSD定义(这个XSD显然还包括XSD类型的额外信息.)
  2. 使用Java XML数据绑定框架(如ADB或JiXB)从步骤1中的我自己的XSD文件生成数据绑定类
  3. 使用具有相同数据绑定框架的Java SOAP框架(如Axis2或CXF)从WSDL生成数据绑定类(这将使我能够在生成XML时直接使用Web服务检索的对象.)

我将在我自己的XSD文件中使用的XSD类型,但是在WSDL中定义,可能会发生变化.每当它们发生变化时,我想再次自动处理XSD和WSDL数据绑定.(如果变化足够大,这可能会触发一些开发工作.(但通常不会.))

我的问题:

在步骤1中,我需要一个XSD引用与Web服务相同的类型.

WSDL引用另一个WSDL,它引用另一个WSDL等.最终,有一个带有所需内联XSD类型的WSDL.据我所知,没有办法从XSD直接引用WSDL的内联XSD类型.

我认为最可行的方法是在自动处理(数据绑定之前)中包含一个额外步骤,该步骤将内联XSD从WSDL提取到其他XSD文件中.然后,我自己的XSD文件可以引用这些其他XSD文件.

我想避免的事情:

  • 手动将内联XSD粘贴到XSD文件中(我正在寻找自动过程.)
  • 任何手动步骤.(就像手动确定包含内联类型的WSDL一样.(WSDL的位置确实也发生了变化.))
  • 在我自己的XSD中使用xsd:any.我想我自己的XSD文件是正确的.
  • 使用非Java技术(如.NET)
  • 大量的实施(但是关于如何实现这样的提取的提示仍然是受欢迎的)

PS:我发现了一些类似的问题,但他们都有这样的回答:WTH你想这样做吗?这就是我相当大的背景故事的原因.

Mik*_*uka 3

我不知道有哪个库可以为您执行此操作,但绝对可以通过一些努力来实现(约 200 行)。一个粗略的元程序,用于生成所有内联和包含的 XSD:

method processWSDL(Document wsdl) {
    for each ("/wsdl:definitions/wsdl:types/xsd:schema" in wsdl) {
        call processXSD("inline_[i].xsd",".")
    }
    for each ("/wsdl:definitions/wsdl:import" in wsdl) {
        Document x = read and parse ("@location")
        if (x is WSDL) call processWSDL(x)
        else if (x is XSD) call processXSD("@location", x)
    }
}

method processXSD(String filename, Document xsd) {
    write "xsd" to a new file "filename"   // if 'filename' is a URL, take only the part after the last '/'
    for each ("/xsd:schema/xsd:import" or "/xsd:schema/xsd:include" in xsd) {
        if ("@schemaLocation" is local reference) {     // no 'http://' prefix
            Document x = read and parse ("@schemaLocation")
            call processXSD("@schemaLocation", x)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

它不是一个完整的解决方案,例如,不处理在内联模式之外定义的名称空间前缀,但希望提供一个良好的起点。