代码之家  ›  专栏  ›  技术社区  ›  Caleb Hattingh

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

  •  5
  • Caleb Hattingh  · 技术社区  · 16 年前

    我对Web服务完全陌生,但对Delphi并不陌生。

    我正在使用“WSDL导入器”向导将WSDL文件导入Delphi2010。WSDL文件包含一些Delphi完全忽略的“attributeGroup”标记,这可能是一个bug,尽管我还没有在Quality Central上找到有关此问题的条目,但仅在以下论坛中提到 here here .

    我的问题有几个部分:

    1. 最好的解决方法是什么?
    2. 我编写了一个python脚本来格式化WSDL文件,这样所有对attributeGroup标记的引用都将替换为在attributeGroups中定义的属性声明;换句话说,扁平化引用。输出通过“WSDL导入器”向导成功导入到Delphi中,看起来是正确的,但是我还没有测试通过这个新的WSDL文件构建的消息是否可以正常工作。这个策略是否可行,或者我应该现在就退出,转而做更有成效的事情?

    更新

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

    4 回复  |  直到 10 年前
        1
  •  2
  •   Caleb Hattingh    15 年前

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

    根据 this post ,在导入WSDL文件时,.NET wsdl.exe工具无法识别某些标记。根据 MSDN :

    属性组 被忽视了。DataContractSerializer不支持使用xs:group、xs:attributeGroup和xs:attribute。这些声明作为xs:schema的子级被忽略,但不能从complexType或其他支持的构造中引用。

    这种行为也被描述为 MSDN blogs . 在我的特定情况下,导致问题的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>
    

    似乎 <xs:attributeGroup ref="TelephoneInfoGroup"/> 正在被.NET wsdl.exe工具忽略,就像被Delphi WSDL导入程序忽略一样。在这种情况下,Delphi和.NET中的导入都失败了,WSDL文件可能必须更改,这意味着我最终必须使用自制的python ref flattner。

        2
  •  1
  •   mjn anonym    16 年前

    Delphi2009和标准SOAP服务(CRM)也有类似的问题。它与attributeGroup无关。我们发现了太多的不兼容性,最终决定使用一个小的C应用程序作为真正基于.NET的服务的代理。

        3
  •  1
  •   Miel    15 年前

    我是你第一次推荐的海报。我想我发现这个bug从来没有被修复过。

    我后来张贴 another question 在Embarcadero开发者网络上,Nick Hodges说

    我们的重点是客户机开发[…]如果您希望构建SOAP服务器,那么我建议您也让Delphi Prism看看。

    为了开发我们的SOAP服务器,我们决定改用C。我决定让服务与一个数据库对话,然后我们的Delphi应用程序就可以访问这个数据库。

    后来我在Delphi下也遇到了客户机开发方面的问题,所以我们在C中也做了这个。这次C类是COM可见的,可以从Delphi访问。似乎工作得很好。

    问候,Miel。

        4
  •  0
  •   dan-gph    10 年前

    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)
    
    推荐文章