开发者

"attributeGroup" references ignored by Delphi WSDL Import Tool

开发者 https://www.devze.com 2023-01-01 14:15 出处:网络
I am completely new to web services, but not new to Delphi. I am importing a WSDL file into Delphi 2010 with the \"WSDL Importer\" wizard.The WSDL file contains some \"attributeGroup\" tags which Del

I am completely new to web services, but not new to Delphi.

I am importing a WSDL file into Delphi 2010 with the "WSDL Importer" wizard. The WSDL file contains some "attributeGroup" tags which Delphi completely ignores, which is presumably a bug, although I haven't yet found an entry on Quality Central for this issue, only mentions in forums like here and here.

My question has several parts:

  1. What is the best workaround?
  2. I have written a Python script to format the WSDL file such that all references to attributeGroup tags are replaced with the declaration of the attributes defined in the attributeGroups; in other words, flattening the references. The output is successfully imported into Delphi via the "WSDL importer" wizard, and looks correct, but I have yet to test whether the messages constructed via this new WSDL file will work correctly. Is this strategy likely to be viable, or should I quit now and move onto something else more productive?

Update

Based on my experiences, and the answers in this question, I decided to go the wrapper route with a C# console application that eats JSON input data and outputs JSON reply data. A Delphi app d开发者_运维知识库rives the C# app. The SOAP part of the whole thing is now effortless, and "just works" in C#.NET, and the rest of the functionality is handled well by Delphi. I would recommend this route to anyone else with similar problems. I did try exporting a C# SOAP assembly as a COM library, and connecting to that from Delphi, but it became very complex, because the SOAP specification in my particular app is large and somewhat complex.


Ok, this one took a while.

According to this post, there are certain tags that the .NET wsdl.exe tool just won't recognize when importing a wsdl file. According to MSDN:

attributeGroup: Ignored. DataContractSerializer does not support use of xs:group, xs:attributeGroup, and xs:attribute. These declarations are ignored as children of xs:schema, but cannot be referenced from within complexType or other supported constructs.

This behaviour is also described (albeit in a very hard-to-understand manner) on one of the MSDN blogs. In my specific case, the particular part of the wsdl file causing the problem looks like this:

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

It seems that the <xs:attributeGroup ref="TelephoneInfoGroup"/> is being ignored by the .NET wsdl.exe tool, just like it was being ignored by the Delphi wsdl importer. In such a situation, where importing fails in both Delphi and .NET, the wsdl file probably has to be changed, and that means I will have to use my home-made python ref-flattener after all.


We had a similar problem with Delphi 2009 and a standard Soap service (CRM). It was not related to attributeGroup. We found so many incompatibilities that we finally decided to use a small C# application as a proxy for the real .Net based service.


I was the poster of the first reference you give. I think I found out that this bug has never been fixed.

I later posted another question on the Embarcadero Developer Network where Nick Hodges said that

We are concentrating on client development [...] if you are looking to build SOAP servers, then I'd suggest that you also give Delphi Prism a look.

We decided to switch to C# for development of our SOAP servers. I decided to let the service talk to a database, which is then accessed by our Delphi application.

Later I ran into problems with client development under Delphi as well, so we're doing that in C#, too. This time the C# class is com visible and can be accessed from Delphi. Seems to work fine.

Regards, Miel.


The Delphi WSDL importer can't handle <xsd:attributeGroup ref="..."> elements, but you can replace those with the actual attributes that are referenced, which the importer can deal with.

Below is a PowerShell script that does this replacement.

The script is unpolished. It's just what I created for my own needs. It may work for you too, or at least it should give you a starting point.

$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)
0

精彩评论

暂无评论...
验证码 换一张
取 消