如何引用同一WSDL文件中定义的模式?

时间:2015-09-22 16:54:33

标签: xsd

我有一个wsdl文件,为同一个命名空间定义了两个模式,如下所示:

<wsdl:types>
   <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://example.com/payments"
                attributeFormDefault="unqualified" elementFormDefault="qualified"
                targetNamespace="http://example.com/payments">
        <xsd:complexType name="TestType">
            <xsd:sequence>
                <xsd:element name="Version" type="xsd:string" />
            </xsd:sequence>
        </xsd:complexType>
    </xsd:schema>
    <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://example.com/payments"
                attributeFormDefault="unqualified" elementFormDefault="qualified"
                targetNamespace="http://example.com/payments">
        <xsd:element name="TestRequest">
            <xsd:complexType>
                <xsd:sequence>
                    <xsd:element name="Header" type="TestType"/>
                </xsd:sequence>
            </xsd:complexType>
        </xsd:element>
    </xsd:schema>
</wsdl:types>

无法从TestType引用TestRequest。我找到了几个answers,通过xsd:include显示你是如何为不同的文件做的那样(因为我使用相同的targetNamespace),但我很茫然如何给schemaLocation包括?

请注意,这不是我应该做的事情不是问题。我知道如果我将元素定义移动到相同的模式定义中,问题就会消失。

2 个答案:

答案 0 :(得分:2)

对于嵌入在WSDL中的XSD,考虑到您在问题中链接的答案,事情与您所看到的不同。

简答:

  • 一个无法在嵌套在WSDL类型部分中的模式之间创建xsd:include references

  • xsd:大多数WSDL处理器都支持import。但是,您提供schemaLocation属性。实际上,它创建了一个悬空模式引用,其中WSDL本身的行为类似于XML目录。

没有标准的方法指向任意XML文件中的模式(除了.XSD文件格式,其中整个文件仅用于一个模式)。当然,XPointer或类似的东西可能有用;但似乎没有人在XSD或WSDL处理器中实现此解决方案。

具有相同命名空间的模式不起作用的事实表明WSDL处理器的实现存在限制。应该没有理由解决悬挂导入,但不能解析具有目标命名空间的模式。后一个亮点的原因是可以包含和/或导入没有命名空间的模式,这会导致歧义。

答案 1 :(得分:1)

WSDL本身不是XSD Schema语言,所以要从XSD文件通过xs:include引用它,你必须摆脱周围的wsdl:types,你必须存储两个架构和#39 ; s在单独的文件中(或者,因为它们在同一个命名空间中,只需删除额外的xsd:schema元素,但不删除其内容)。

你可以用一个简单的XSLT来做到这一点(为简洁起见,删除了根注释,确保声明相关的命名空间):

<xsl:template match="node() | @*">
    <xsl:copy>
        <xsl:apply-templates select="node() | @*" />
    </xsl:copy>
</xsl:template>

<xsl:template match="wsdl:types">
    <xsl:apply-templates select="xsd:schema[1]" />
</xsl:template>

<xsl:template match="xsd:schema">
    <xsl:copy>
        <xsl:copy-of select="@*" />
        <xsl:apply-templates />
        <xsl:apply-templates select="following-sibling::xsd:schema/*" />
    </xsl:copy>
</xsl:template>

如果这是一次性任务,那么您只需针对WSDL运行一次,保存结果并通过相对文件URI引用它们。如果您需要更频繁地执行此操作,则应该自动执行此操作。