独立元素 在SOAP中,一个独立元素表示至少被一个多引用存取元素引用的类型的实例。所有的独立元素用soap:id属性作标记,而且这个属性的值在整个SOAP envelope中必须是唯一的。独立的元素被编码就好象是它们被一个存取元素打包,这个存取元素的标记名是实例的名域限制的类型名。在上面的例子中,实例的名域限制的类型名是t:adjustment。 SOAP限制独立元素能被编码的场所。SOAP定义了一个能适用于任何元素的属性:(soap ![]() ![]() 假设transfer 类对应于一个方法请求。如果transfer类型不是一个包,被to和from存取元素引用的独立元素将作为soap:Body元素的直接子元素出现,如图10所示。如果transfer类型是一个合法的SOAP包类型,编码可能象图11所示。注意,因为transfer元素是一个包,所有多引用存取器元素都引用被包含的元素。这使得把transfer元素看成一个能从它的父辈元素中分离出的独立的XML代码段变得更为容易。 多引用存取元素总是引用独立元素的模型是有一个例外的。SOAP允许包含字符串和二进值数据的存取元素是多引用存取元素的目标。这意味着下面的代码是合法的: <t:mytype> <field1 soap:href="#id1" /> <field2 soap:id="id1">Hello, SOAP</field2> </t:mytype> 尽管事实是存取元素2有一个soap:id属性,它实际上是一个存取元素而不是独立元素。 SOAP数组 数组被编码为组合类型的一个特殊的例子。在SOAP中,一个数组必须有一个秩(维数)和一个容量。一个数组被编码为一个组合类型,其中每一个数组元素被编码为一个子元素,这个子元素的名字是元素的名域限制的类型名。 假设有下面的COM IDL类型定义: struct POINTLIST { long cElems; [size_is(cElems)] POINT points[]; }; 这个类型的实例将被序列化为: <t ![]() <cElems>3</cElems> <points xsd:type=‘t ![]() <POINT>lt;x>3</x>lt;y>4</y>lt;/POINT> <POINT>lt;x>7</x>lt;y>5</y>lt;/POINT> <POINT>lt;x>1</x>lt;y>9</y>lt;/POINT> </points> <t ![]() 如果points域被标记为[ptr]属性,这个编码将用一个多引用存取元素,如下所示: <t ![]() <cElems>3</cElems> <points soap:href="#x9" /> </t ![]() <t:ArrayOfPOINT soap:id=‘x9‘ xsd:type=‘t ![]() <POINT>lt;x>3</x>lt;y>4</y>lt;/POINT> <POINT>lt;x>7</x>lt;y>5</y>lt;/POINT> <POINT>lt;x>1</x>lt;y>9</y>lt;/POINT> </t:ArrayOfPOINT> 当把一个数组编码为一个独立元素时,标记名是带前缀ArrayOf的类型名。 象NDR和CDR一样,SOAP支持部分转换的数组。如果子元素的数量少于所声明的容量,这些元素被假设正从数组的末尾丢失。这能够通过在正包含的数组元素上使用soap ![]() <t:ArrayOfPOINT soap:id=‘x9‘ xsd:type=‘t ![]() soap ![]() <POINT>lt;x>1</x>lt;y>9</y>lt;/POINT> </t:ArrayOfPOINT> soap ![]() <t:ArrayOfPOINT soap:id=‘x9‘ xsd:type=‘t ![]() <POINT soap:position=‘[3]‘>lt;x>3</x>lt;y>4</y>lt;/POINT> <POINT soap:position=‘[7]‘>lt;x>4</x>lt;y>5</y>lt;/POINT> </t:ArrayOfPOINT> 在这个例子中,元素0到2,4到6,以及8到9都不是被转换的。 请注意,在SOAP中数组的精确语法在这篇文章写作时还在被重新审查以调整到即将推出的W3C XML Schema规范中。要不断了解SOAP规范的最新版本来获得更多的细节。 |