【问题标题】:What is the difference between Type and Element in WSDL?WSDL 中的类型和元素有什么区别?
【发布时间】:2010-11-13 09:56:50
【问题描述】:

在 WSDL 文件中,函数可以返回类型或元素。到目前为止,我只使用自定义类型作为结果。但是,我想知道什么时候 Element 应该比 Type 更合适?它们有什么区别?

有什么区别

<wsdl:message name="MyFunction">
    <wsdl:part name="parameters" element="tns:Person"></wsdl:part>
</wsdl:message>

<wsdl:message name="MyFunction">
    <wsdl:part name="parameters" type="tns:Person"></wsdl:part>
</wsdl:message>

从客户端的角度来看(使用 Web 服务的应用程序)?

正如 skaffman 所指出的,上述问题引出了另一个问题。有什么区别

<xs:element name="Person" ... >
 ...
</xs:element>

<xs:complexType name="Person">
   ...
</xs:complexType>

?

【问题讨论】:

  • 你的问题比那 14 票更有价值,至少对我来说。

标签: wsdl schema


【解决方案1】:
<xs:element name="person" type="persontype"/>

<xs:complexType name="persontype">
  <xs:sequence>
    <xs:element name="firstname" type="xs:string"/>
    <xs:element name="lastname" type="xs:string"/>
  </xs:sequence>
</xs:complexType>

type 属性的&lt;element&gt; 引用name 属性的&lt;complexType&gt;


<wsdl:message name="MyFunction">
    <wsdl:part name="parameters" element="tns:person"></wsdl:part>
</wsdl:message>

<wsdl:message name="MyFunction">
    <wsdl:part name="parameters" type="tns:person"></wsdl:part>
</wsdl:message>
  • &lt;part&gt; 参数与&lt;types&gt; 容器元素中定义的具体类型相关联。和&lt;part&gt; 可以通过type 属性或&lt;element&gt; 通过元素属性引用&lt;complexType&gt;,如上所示。
  • 它可以是&lt;complexType&gt;&lt;portType&gt; 或任何一个,由type 属性引用。

【讨论】:

    【解决方案2】:

    不止于此。

    标准中存在一些可能导致互操作性问题的模糊性。您必须使用类型或元素,具体取决于您使用的是基于文档的服务还是基于 RPC 的服务。

    也有歧义。如果你说

    <wsdl:message name="message1" type="ns:type1"/>
    

    那么您已经说过消息的内容必须针对类型“ns:type1”进行验证。但是您对包含内容的元素只字未提。它将在哪个命名空间中?

    有关这方面的一些规则,请参阅WS-I Basic Profile


    cmets 中有一些关于“document/literal”与“document/literal/wrapped”的讨论。这是我的看法。

    我刚刚创建了一个网络服务。以下是全部内容:

    using System.Web.Services;
    
    namespace WebService1
    {
        [WebService(Namespace = "http://tempuri.org/")]
        [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
        [System.ComponentModel.ToolboxItem(false)]
        public class SimpleMathService : WebService
        {
            [WebMethod]
            public int Add(int a, int b)
            {
                return a + b;
            }
    
            [WebMethod]
            public int Multiply(int a, int b)
            {
                return a*b;
            }
        }
    }
    

    我不会发布整个 WSDL,但这里是“好的部分”:

    <?xml version="1.0" encoding="utf-8"?>
    <wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:s="http://www.w3.org/2001/XMLSchema" 
        xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
         targetNamespace="http://tempuri.org/" xmlns:tns="http://tempuri.org/" >
        <wsdl:types>
            <s:schema elementFormDefault="qualified" targetNamespace="http://tempuri.org/">
                <s:element name="Add">
                    <s:complexType>
                        <s:sequence>
                            <s:element minOccurs="1" maxOccurs="1" name="a" type="s:int"/>
                            <s:element minOccurs="1" maxOccurs="1" name="b" type="s:int"/>
                        </s:sequence>
                    </s:complexType>
                </s:element>
                <s:element name="AddResponse">
                    <s:complexType>
                        <s:sequence>
                            <s:element minOccurs="1" maxOccurs="1" 
                               name="AddResult" type="s:int"/>
                        </s:sequence>
                    </s:complexType>
                </s:element>
                <s:element name="int" type="s:int"/>
            </s:schema>
        </wsdl:types>
        <wsdl:message name="AddSoapIn">
            <wsdl:part name="parameters" element="tns:Add"/>
        </wsdl:message>
        <wsdl:message name="AddSoapOut">
            <wsdl:part name="parameters" element="tns:AddResponse"/>
        </wsdl:message>
        <wsdl:portType name="SimpleMathServiceSoap">
            <wsdl:operation name="Add">
                <wsdl:input message="tns:AddSoapIn"/>
                <wsdl:output message="tns:AddSoapOut"/>
            </wsdl:operation>
        </wsdl:portType>
        <wsdl:binding name="SimpleMathServiceSoap" type="tns:SimpleMathServiceSoap">
            <soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
            <wsdl:operation name="Add">
                <soap:operation soapAction="http://tempuri.org/Add" style="document"/>
                <wsdl:input>
                    <soap:body use="literal"/>
                </wsdl:input>
                <wsdl:output>
                    <soap:body use="literal"/>
                </wsdl:output>
            </wsdl:operation>
        </wsdl:binding>
        <wsdl:service name="SimpleMathService">
            <wsdl:port name="SimpleMathServiceSoap" binding="tns:SimpleMathServiceSoap">
                <soap:address location="http://localhost:5305/SimpleMathService.asmx"/>
            </wsdl:port>
        </wsdl:service>
    </wsdl:definitions>
    

    请注意“包装”一词是如何不出现的。 IBM 在他们的文档中所说的“文档/文字/包装”只是“文档/文字”,它恰好使用单个消息部分,恰好有一个从服务名称派生的名称,并且恰好是指到一个元素,并且恰好包含操作的两个参数。

    这里没有什么神奇的,这里没有什么不标准的。

    在许多标准组织中,公司最终都偏袒一方。对于 SOAP,我们有“RPC 端”和“文档端”。 RPC 对很多人来说更为熟悉——它与函数调用一一对应。 Document 不太熟悉,需要您实际考虑简单的 XML。也许 IBM 在 RPC 方面,我不知道。


    我现在已经完成了 IBM 文档,哪种 WSDL 样式。总结是:

    总结

    有四种绑定样式(确实有五种,但 document/encoded 没有意义)。虽然每种样式都有其位置,但在大多数情况下,最好的样式是文档/文字包装。


    我还想根据消息中是否存在操作名称来对文档中讨论调度难度级别的地方做出反应。这是一个非问题。如果您阅读该文档,您会注意到它从未在 &lt;binding&gt; 部分讨论任何内容。 “无操作名”问题的解决办法就在那里。

    <wsdl:binding name="SimpleMathServiceSoap" type="tns:SimpleMathServiceSoap">
        <soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
        <wsdl:operation name="Add">
            <soap:operation soapAction="http://tempuri.org/Add" style="document"/>
    

    soapAction 在请求的 HTTP 头中发送,可用于调度:

    POST /SimpleMathService.asmx HTTP/1.1
    Host: localhost
    Content-Type: text/xml; charset=utf-8
    Content-Length: length
    SOAPAction: "http://tempuri.org/Add"
    
    <?xml version="1.0" encoding="utf-8"?>
    <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
           xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
           xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
      <soap:Body>
        <Add xmlns="http://tempuri.org/">
          <a>int</a>
          <b>int</b>
        </Add>
      </soap:Body>
    </soap:Envelope>
    

    【讨论】:

    • 那么,如果我使用基于 RPC 的服务,我的所有函数都应该返回一个 Schema 元素?
    • 我不知道。我不使用它们。我发现它们有问题。我总是使用文档/文字。
    • 对于文档/文字,操作名称丢失。我有几个具有相同参数集的函数,所以我不能使用文档/文字。尽管如此,您是否曾经使用过 Schema 元素作为函数结果?
    • 这很奇怪。您确定您使用的是文档/文字吗?根据这篇文章ibm.com/developerworks/webservices/library/ws-whichwsdl 清单 5,这是一个 rpc/literal 消息。
    • 我明白了。继续阅读。 Microsoft 使用他们所谓的“文档/文字包装”,就好像它有问题一样。当他们说有必要做出“有根据的猜测”时,他们几乎是在撒谎。废话。消息的一部分是模式中定义的类型的元素。该操作使用该消息。无需猜测。
    【解决方案3】:

    我无法评论问题的 WSDL 部分,但我会回答 XML Schema 部分。

    &lt;xs:complexType&gt; 定义了一个类型,它描述了元素的内容,而不描述元素本身(即它的名称)。 &lt;xs:element&gt; 描述了一个元素(特别是它的名称),而不是它的类型。但是,&lt;xs:element&gt; 总是引用它所描述的元素内容的类型。这可以是对架构中其他地方的现有类型(包括但不限于&lt;xs:complexType&gt; - 例如也可以是&lt;xs:simpleType&gt;)定义的引用,或内联&lt;xs:complexType&gt; 定义:

    <xs:element name="foo">
       <xs:complexType>
          ...
       </xs:complexType>
    </xs:element>
    

    由于上述构造非常常见,您实际上可以完全省略&lt;xs:complexType&gt;,它会被暗示。

    至于你是否应该总是单独定义类型然后在元素声明中引用它们,或者你是否应该更喜欢在元素声明中内联定义元素类型,这是一个风格问题。

    【讨论】:

    • 根据 skaffman 的说法,可以命名 complexType。那么,命名complexType 和用element 包装类型有什么区别?
    • 如果你命名它,你可以将它应用到几个不同的元素声明,和/或从中派生其他类型。因此,您可以拥有 complexType Person,通过扩展从中派生 complexType Employee(添加更多子元素来描述属性),然后将这些类型分配给元素“Person”和“Employee”,例如。
    【解决方案4】:

    您使用哪一个取决于它所引用的架构。如果 tns:Person 在架构中定义为:

    <xs:element name="Person" ... >
     ...
    </xs:element>
    

    然后你使用

    <wsdl:part name="parameters" element="tns:Person">
    

    另一方面,如果模式定义为

    <xs:complexType name="Person">
       ...
    </xs:complexType>
    

    然后你使用

    <wsdl:part name="parameters" type="tns:Person">
    

    所以问题实际上是 Schema 元素和 Schema 类型之间的区别。

    【讨论】:

    • 是的,我想知道何时应该创建 Schema 类型以及何时创建 Schema 元素。或者,也许在这种情况下没有区别?
    • 您最好不要自己创建任何一个,直到您对这些东西有了更好的了解。同时,依赖于自动生成的 WSDL 和模式文件。
    猜你喜欢
    • 2013-06-13
    • 1970-01-01
    • 1970-01-01
    • 2017-06-11
    • 1970-01-01
    • 2011-05-29
    • 2011-12-25
    • 2014-09-17
    相关资源
    最近更新 更多