Circular reference error while trying to import WSDL into Visual Studio 2013

不打扰是莪最后的温柔 提交于 2019-12-05 22:51:52
Abel

I have played a little more with your schemas and WSDL and found an answer to your issue, although you may not like it...

  • There is no difference in unchecking the re-use types checkbox, because that only applies to situations where you re-import the definitions
  • After import, Visual Studio places all XSD's under the service reference (click "show hidden files"). Select siri.xsd and it will show you that it cannot locate two includes.
  • To fix the include-issue, I changed the include URI to an absolute URI. This resolved the issue with Visual Studio not being able to locate the files and it then copies them properly.
  • When now rebuilding, it will show in the Debug Output window the proper validation errors. Most importantly, it complains about redefinitions. I managed to resolve this by removing any reference to xml.xsd and simplifying the few places where it was used (xml:lang only). Next thing I did was to place all XSD's directly under the root and fixed all references in xsl:import and xsl:include to reflect this. Many redefinition errors now disappeared
  • It now complains about an xs:group being circular (it did so before, but I wanted other warnings to be out of the way):

    Microsoft.ServiceModel.targets(113,5): error : Group 'ServiceDeliveryBodyGroup' from targetNamespace='http://www.siri.org.uk/siri' has invalid definition: Circular group reference.

    This is a tricky one, because I didn't manage to track why it is considered circular, but if it is, this is allowed in XSD. It gets imported twice, but that does not seem to be the cause, I think this is deliberate.

After some further searches, it appears that Microsoft's xsd.exe, which is similar to the code used by wsdl.exe, svcutil and add a service reference, has acknowledged this to be a limitation of their XSD-to-object mapping tools.

I think your best bet is to take that group and make it non-circular. After that, it should accept the schemas as valid and proceed. The fact that the importer complains about wsdl:portType does not point you in the right direction. It complains about that, because it fails to map all types, which results in mapping no types at all, after which also wsdl:portType is unknown, hence the error.

It is very well possible that the other steps outlined above become obsolete after you fix the ServiceDeliveryBodyGroup type. The other errors were actually warnings, and I believe that Microsoft essentially ignores such redefinitions anyway and will proceed "normally".

It turns out that the circular reference goes like this:

  • The ServiceDeliveryStructure complexType is based on
  • ProducerResponseStructure, which is based on
  • the abstract ResponseStructure conplexType but contains
  • SiriServiceDeliveryGroup group, which contains
  • StopMonitoringDelivery element, which may be substituted for
  • the abstract AbstractFunctionalServiceDelivery element, which may be substituted for
  • the abstract AbstractResponse element which is of
  • again, the abstract ResponseStructure complexType

hence the circularity.

The way I discovered this is by commenting out each component of the implicated group, ServiceDeliveryBodyGroup. It referenced a few elements which had both their type (referencing some complexType) and substitutionGroup (referencing some abstract element) attributes set. Removing the type didn't remove the circularity, and since the abstract types were simple , it singled-out the abstract ResponseStructure complexType. Going back to ServiceDeliveryBodyGroup, to see where it descends from (it was the only option left for making anything circular, after going through each part of its contents), quickly revealed the problem.

On another note, it seems to me wrong, that an element may be substituted by an element for which abstract="true". But I don't know that much about XSD. So this might make sense.

Rather than trying to figure that out, I decided to have the ServiceDeliveryStructure, rather than basing itself on ProducerResponseStructure, to contain the group the latter contains. I would imagine this is the equivalent of using mix-in inheritance rather than true inheritance. AFAIK it should retain the same XML structure, indeed -- obscuring slightly the dependency tree -- but allowing for a full import into Visual Studio, as needed.

In more detail, I replace the following

<xsd:complexContent>
    <xsd:extension base="ProducerResponseStructure">
        <xsd:sequence>
            <xsd:group ref="ServiceDeliveryBodyGroup"/>
        </xsd:sequence>
        <xsd:attribute name="srsName" type="SrsNameType" />
    </xsd:extension>
</xsd:complexContent>

with the following

<xsd:sequence>
    <xsd:group ref="ProducerResponseEndpointGroup"/>
    <xsd:group ref="ServiceDeliveryBodyGroup"/>
</xsd:sequence>
<xsd:attribute name="srsName" type="SrsNameType" />

(note: <xsd:annotation/> tag in original code was left out for brevity)

I will test it, and if it works as expected, I will accept my own answer...

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!