WSDL中Type和Element有什么区别?

时间:2009-07-23 14:23:47

标签: wsdl schema

在WSDL文件中,函数可以返回Type或Element。到目前为止,我只使用自定义类型作为结果。但是,我想知道什么时候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服务的应用程序)?

正如斯卡弗曼指出的那样,上述问题引出了另一个问题。有什么区别

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

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

4 个答案:

答案 0 :(得分:16)

还有更多的东西。

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

也存在歧义。如果你说

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

然后你说过消息的内容必须根据类型“ns:type1”进行验证。但是你对包含内容的元素一无所知。它的名称空间是什么?

有关此问题的一些规则,请参阅WS-I Basic Profile


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

我刚刚创建了一个Web服务。这就是整个事情:

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在他们的文档中调用“document / literal / wrapped”只是“document / literal”,碰巧使用单个消息部分,恰好有一个名称派生自服务名称,而且恰好引用到一个元素,它碰巧包含操作的两个参数。

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

在许多标准组织中,公司最终会采取行动。在SOAP的情况下,我们有“RPC方面”和“文档方面”。 RPC对许多人来说比较熟悉 - 它通过函数调用一对一映射。文档不太熟悉,并且要求您实际考虑简单的XML。也许IBM在RPC方面,我不知道。


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

摘要

有四种绑定样式(实际上有五种,但文档/编码没有意义)。虽然每种风格都有它的位置,但在大多数情况下,最好的风格是文档/文字包装。


我还想根据消息中是否存在操作名称,对文档中讨论调度难度的地方作出反应。这不是问题。如果您阅读该文档,您会注意到它从未在<binding>部分讨论任何内容。那里有“无操作名称”问题的解决方案。

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

答案 1 :(得分:10)

您使用哪一个取决于它所引用的架构。如果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类型之间的区别。

答案 2 :(得分:2)

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

<xs:complexType>定义了一种类型,它描述了一个元素的 content ,而没有描述元素本身(即它的名字)。 <xs:element>描述了元素(特别是其名称),但不是它的类型。但是,<xs:element>始终引用它所描述的元素内容的类型。这可以是对现有类型的引用(包括但不限于<xs:complexType> - 例如,它也可以是<xs:simpleType>定义在架构中的其他位置,或者是内联<xs:complexType>定义:

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

由于上面的结构很常见,你实际上可以完全省略<xs:complexType>,并且它将被隐含。

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

答案 3 :(得分:0)

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

<element>属性的type指的是<complexType>属性的name

<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>
  • <part>参数与<types>容器元素中定义的具体类型相关联。 <part> <complexType>可以引用type属性,<element>引用元素属性,如上所示。
  • 可以是<complexType><portType>或任何由type属性引用的。