Delphi WSDL导入工具忽略“attributeGroup”引用

时间:2010-06-01 14:37:40

标签: delphi soap attributes wsdl

我是Web服务的新手,但对Delphi来说并不陌生。

我使用“WSDL Importer”向导将WSDL文件导入Delphi 2010。 WSDL文件包含Delphi完全忽略的一些“attributeGroup”标签,这可能是一个错误,虽然我还没有在Quality Central上找到关于此问题的条目,只在here和{{3}等论坛中提及}}

我的问题有几个部分:

  1. 最佳解决方法是什么?
  2. 我编写了一个Python脚本来格式化WSDL文件,以便对attributeGroup标签的所有引用都替换为attributeGroups中定义的属性的声明;换句话说,展平参考文献。输出通过“WSDL导入器”向导成功导入Delphi,看起来正确,但我还没有测试通过这个新的WSDL文件构造的消息是否能正常工作。这种策略是否可行,或者我现在应该放弃并转向其他更有效的方法?
  3. 更新

    根据我的经验和这个问题的答案,我决定使用C#控制台应用程序进行包装路由,该应用程序使用JSON输入数据并输出JSON回复数据。 Delphi应用程序驱动C#应用程序。整个事物的SOAP部分现在毫不费力,并且在C#.NET中“正常工作”,其余功能由Delphi很好地处理。我会向其他有类似问题的人推荐这条路线。我确实尝试将C#SOAP程序集导出为COM库,并从Delphi连接到它,但它变得非常复杂,因为我的特定应用程序中的SOAP规范很大而且有点复杂。

4 个答案:

答案 0 :(得分:2)

好的,这个花了一段时间。

根据this post,导入wsdl文件时,某些标记表明.NET wsdl.exe工具无法识别。根据{{​​3}}:

  

attributeGroup :忽略。 DataContractSerializer不支持使用xs:group,xs:attributeGroup和xs:attribute。这些声明作为xs:schema的子节点被忽略,但不能从complexType或其他受支持的构造中引用。

MSDN之一上也描述了这种行为(尽管以一种非常难以理解的方式)。在我的特定情况下,导致问题的wsdl文件的特定部分如下所示:

 <xs:complexType name="PhonesType">
     <xs:annotation>
         <xs:documentation xml:lang="en">Provides detailed phone information.</   xs:documentation>
     </xs:annotation>
     <xs:sequence>
         <xs:element maxOccurs="unbounded" name="Phone">
             <xs:annotation>
                 <xs:documentation xml:lang="en">Used to pass detailed phone information.</xs:documentation>
             </xs:annotation>
             <xs:complexType>
                 <xs:attributeGroup ref="TelephoneInfoGroup"/>
                 <xs:attributeGroup ref="ID_OptionalGroup">
                     <xs:annotation>
                         <xs:documentation xml:lang="en">The ID attribute in this group is a unique identifying value assigned by the creating system and may be used to reference a primary-key value within a database or in a particular implementation.</xs:documentation>
                     </xs:annotation>
                 </xs:attributeGroup>
             </xs:complexType>
         </xs:element>
     </xs:sequence>
 </xs:complexType>

.NET wsdl.exe工具似乎忽略了<xs:attributeGroup ref="TelephoneInfoGroup"/>,就像它被Delphi wsdl导入器忽略一样。在这种情况下,在Delphi和.NET中导入失败的情况下,可能必须更改wsdl文件,这意味着我将不得不使用我自己的python ref-flattener。

答案 1 :(得分:1)

我们在Delphi 2009和标准Soap服务(CRM)方面遇到了类似的问题。它与attributeGroup无关。我们发现了很多不兼容性,我们最终决定使用一个小型C#应用程序作为真正基于.Net的服务的代理。

答案 2 :(得分:1)

我是你给出的第一个参考文献的海报。我想我发现这个bug从未修复过。

我后来在Embarcadero开发者网络上发布了another question,其中Nick Hodges说

  

如果您希望构建SOAP服务器,我们专注于客户端开发[...],那么我建议您也让Delphi Prism看一下。

我们决定切换到C#来开发我们的SOAP服务器。我决定让服务与数据库通信,然后由我们的Delphi应用程序访问。

后来我在Delphi下遇到了客户端开发问题,所以我们也在C#中做了这个。这次C#类是可见的,可以从Delphi访问。似乎工作正常。

问候,Miel。

答案 3 :(得分:0)

Delphi WSDL导入器无法处理<xsd:attributeGroup ref="...">元素,但您可以使用导入的实际属性替换它们,导入器可以处理这些元素。

以下是进行此替换的PowerShell脚本。

脚本未经抛光。这正是我为自己的需求而创造的。它也可能对你有用,或者至少它应该给你一个起点。

$xsdPath = "E:\scratch\InputFile.wsdl"

# Note: Must be full path.
$outPath = "E:\scratch\OutputFile.wsdl"

$xsd = [xml](gc $xsdPath)

$ns = @{xsd="http://www.w3.org/2001/XMLSchema"}

$attrGroupDefs = $xsd | 
    Select-Xml -Namespace $ns -XPath "//xsd:schema/xsd:attributeGroup" |
    select -ExpandProperty Node

$attrGroupRefs = $xsd |
    Select-Xml -Namespace $ns -XPath "//xsd:complexType/xsd:attributeGroup" |
    select -ExpandProperty Node

$attrGroupRefs | % { 
    # the thing to be replaced
    $ref = $_

    $refParent = $ref.ParentNode

    $namespace, $name = $_.ref -split ":"
    $attrs = $attrGroupDefs | ? name -eq $name | select -ExpandProperty attribute

    # remove the reference
    $refParent.RemoveChild($ref)

    # add the actual definitions
    $attrs | % {
        $newNode = $_.CloneNode($true)
        $refParent.AppendChild($newNode)
    }
}

$xsd.Save($outPath)