自动从WSDL提取内联XSD生成XSD文件

9
我正在使用一个第三方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中,我需要一个引用Web服务使用的相同类型的XSD。
WSDL引用另一个WSDL,后者引用另一个WSDL等。最终有一个包含所需内联XSD类型的WSDL。据我所知,没有直接从XSD引用WSDL中的内联XSD类型的方法。
我认为最可行的方法是在自动处理(数据绑定之前)中包含一个额外的步骤,该步骤将内联XSD从WSDL提取到其他XSD文件中。然后,我的XSD文件可以引用这些其他XSD文件。
我想避免的事情:
手动复制内联XSD到XSD文件中(我正在寻找自动过程)。 任何手动步骤。(例如手动确定包含内联类型的WSDL。(该WSDL的位置也会更改。)) 在我的XSD中使用xsd:any。我希望我的XSD文件是正确的。 使用非Java技术(如.NET) 大量的实现(但欢迎关于如何实现此类提取的提示)
PS:我发现了一些类似的问题,但它们都有像“你为什么要那样做?”这样的回答。这就是我背景故事相当大的原因。
2个回答

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)
        }
    }
}

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


我已经猜到这样的事情是必要的。实际上,我希望有更像框架的东西:for(XmlSchema xmlSchema : wsdl.extractNamespaceSchemas()) xmlSchema.writeFile(ns2FileName(xmlSchema.getTargetNamespace())); 啊,世界并不完美... - Steven Geens
@Steven:听起来像是一个开源项目的机会,让世界更加完美一些;-) - Wim Coenen

2
为了让这篇文章保持相关性,自答案被接受以来情况已经发生了变化。在Java中现在可以从WSDL生成所需内容;JAX-WS提供了wsimport工具,它正是所需的:获取WSDL,创建客户端代理以及一堆用于请求的JAXB注释类。
我想说的是,针对@MoizTankiwala的观点,从WSDL导出XSD内容(或将所有外部XSD内容包含在WSDL的类型部分中)的需求依然存在。
前者在某人拥有大量XSD且对于在XSD中有效管理、分析和演化该模型存在普遍关注时是有意义的。
后者也是被追求的,因为一些(主要是)动态语言在生成WSDL到客户端代理方面仍然缺乏完全支持的工具。
我的stackoverflow上的另一个答案谈到了类似的需求,这应该至少对Moiz的请求有所帮助...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接