我目前正在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,所以我做了一些研究,到目前为止我能够说出来
答案 0 :(得分:1)
关于你的第二个最后一个问题:这些XML文件不能被认为是相同的。原因如下:
元素SomeID
和SomeStatus
的命名空间不一样。在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/"
因此,元素SomeID
和SomeStatus
不在任何名称空间中,因为它们缺少名称空间前缀。
相反,c#app中的XML具有以下命名空间
xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
xmlns="http://tempuri.org/"
如您所见,第二个xmlns
属性是默认命名空间属性,因此子元素SomeID
和SomeStatus
位于“http://tempuri.org/”命名空间中。这意味着这些元素具有不同的qualified names,因此不相同。
(如果我不得不猜测,我会认为c#XML是正确的并且Delphi XML有一个错误。但我无法分辨,因为你引用的XSD for the SOAP standard没有特定的架构Body
。)
Delphi XML提供了有关SomeID
和SOME_OK_STATUS
类型的其他信息。这可能对接收器有用,因为SOAP standard“不强制要求这些元素的特定结构或解释,并且没有为Body
内的元素提供指定要完成的处理的标准方法。但是,如果接收方已经知道在这些元素中会发生什么,那么这些属性可能是不必要的。
这些是我看到的XML示例之间的主要逻辑差异。
至于第一个最后一个问题,我们需要看到c#代码,以明确地评论它生成的XML为什么会这样。如果XmlSerializer
用于序列化,则除非forced to do so
xsi:type
信息
答案 1 :(得分:0)
1 - 正如您所说,UTF-8
是默认的,因此可以省略
2 - s
和SOAP-ENV
指的是通过引用相同的命名空间 - http://schemas.xmlsoap.org/soap/envelope/指定的相同类型的对象。您可以点击链接查看对象的架构。这就是说,s
和SOAP-ENV
都是Envelope
类型的对象,如架构中所述
3 - 定义SomeTagName
的对象类型是可选的,因为它没有引用到其他地方,因为它发生在Envelope
声明中引用的Body
对象中使得它需要被定义(通过定义的读取给它一个名称,因为它实际上是由命名空间定义的)。因此,NS1
在一个中声明,而在另一个中以任何名称声明。在这种情况下只需要命名空间,并且都有它。
4 - 我看到的另一个区别是Delphi版本设置了非复杂类型的命名空间(如xsd:int
)。这又是可选的,因为它在模式中设置,应该对此进行规则,如果模式引用了一种类型而请求/响应是另一种,那么我们就会遇到问题。
真正使这两者不同的唯一因素是delphi版本上的有效负载对于可能与移动设备一致的大请求/响应将会大得多