这两个XML是一样的吗?

时间:2014-12-29 12:07:11

标签: c# xml web-services delphi soap

我目前正在delphi 7中编写一个Web服务客户端(服务本身在c#中)。一切似乎工作得很好。当我运行一个小提琴手来看看xml从我的客户端应用程序看起来如何看起来我注意到当我在c#中编写“相同”的客户端应用程序时看起来不同。下面是两个xml的

来自Delphi 7应用程序

<?xml version="1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
  <SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:NS2="http://tempuri.org/">
    <NS1:SomeTagName xmlns:NS1="http://tempuri.org/">
      <SomeID xsi:type="xsd:int">12345</SomeID>
      <SomeStatus xsi:type="NS2:SomeStatusType">SOME_OK_STATUS</SomeStatus>
    </NS1:SomeTagName>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

来自c#app的一个

<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Body>
    <SomeTagName xmlns="http://tempuri.org/">
      <SomeID>12345</SomeID>
      <SomeStatus>SOME_OK_STATUS</SomeStatus>
    </SomeTagName>
  </s:Body>
</s:Envelope>

我不熟练使用xml,所以我做了一些研究,到目前为止我能够说出来

  1. UTF-8是没有编码信息的文档的默认设置 - ref. here - 这意味着没有区别
  2. XML命名空间提供了一种避免元素名称冲突的方法 - ref. here - 命名空间不同(s:和SOAP-ENV :)但是有指定的,并且就我而言,不应该有所不同
  3. 但架构怎么样 - 不确定。在Somevelo或SomeDatus标签中的数据类型中有一些额外的属性。但这来自服务wsdl(我是吗?!)。

    最终问题:

    1. 为什么用c#(vs2012)编写的应用程序不会添加所有额外的架构 信息到xml。如果xml有它们或者它真的很重要吗? 不?
    2. 任何人都可以判断这些是否可以被认为是相同的吗?

2 个答案:

答案 0 :(得分:1)

关于你的第二个最后一个问题:这些XML文件不能被认为是相同的。原因如下:

  1. 元素SomeIDSomeStatus的命名空间不一样。在Delphi XML中,XML中的任何地方都没有指定default namespace。我们只看到以下命名空间:

    • xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
    • xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    • xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    • xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
    • xmlns:NS2="http://tempuri.org/"
    • xmlns:NS1="http://tempuri.org/"

    因此,元素SomeIDSomeStatus不在任何名称空间中,因为它们缺少名称空间前缀。

    相反,c#app中的XML具有以下命名空间

    • xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
    • xmlns="http://tempuri.org/"

    如您所见,第二个xmlns属性是默认命名空间属性,因此子元素SomeIDSomeStatus位于“http://tempuri.org/”命名空间中。这意味着这些元素具有不同的qualified names,因此不相同。

    (如果我不得不猜测,我会认为c#XML是正确的并且Delphi XML有一个错误。但我无法分辨,因为你引用的XSD for the SOAP standard没有特定的架构Body。)

  2. Delphi XML提供了有关SomeIDSOME_OK_STATUS类型的其他信息。这可能对接收器有用,因为SOAP standard“不强制要求这些元素的特定结构或解释,并且没有为Body内的元素提供指定要完成的处理的标准方法。但是,如果接收方已经知道在这些元素中会发生什么,那么这些属性可能是不必要的。

  3. 这些是我看到的XML示例之间的主要逻辑差异。

    至于第一个最后一个问题,我们需要看到c#代码,以明确地评论它生成的XML为什么会这样。如果XmlSerializer用于序列化,则除非forced to do so

    ,否则不会输出非多态字段的xsi:type信息

答案 1 :(得分:0)

1 - 正如您所说,UTF-8是默认的,因此可以省略

2 - sSOAP-ENV指的是通过引用相同的命名空间 - http://schemas.xmlsoap.org/soap/envelope/指定的相同类型的对象。您可以点击链接查看对象的架构。这就是说,sSOAP-ENV都是Envelope类型的对象,如架构中所述

3 - 定义SomeTagName的对象类型是可选的,因为它没有引用到其他地方,因为它发生在Envelope声明中引用的Body对象中使得它需要被定义(通过定义的读取给它一个名称,因为它实际上是由命名空间定义的)。因此,NS1在一个中声明,而在另一个中以任何名称声明。在这种情况下只需要命名空间,并且都有它。

4 - 我看到的另一个区别是Delphi版本设置了非复杂类型的命名空间(如xsd:int)。这又是可选的,因为它在模式中设置,应该对此进行规则,如果模式引用了一种类型而请求/响应是另一种,那么我们就会遇到问题。

真正使这两者不同的唯一因素是delphi版本上的有效负载对于可能与移动设备一致的大请求/响应将会大得多