XML 中的分层记录集
ADO 允许将分层 Recordset 对象持久保存为 XML 格式。 对于分层 Recordset 对象,父 Recordset 中的一个字段的值是另一个 Recordset。 此类字段在 XML 流中表示为子元素,而不是属性。
备注
以下示例演示了这种情况:
Rs.Open "SHAPE {select stor_id, stor_name, state from stores} APPEND ({select stor_id, ord_num, ord_date, qty from sales} AS rsSales RELATE stor_id TO stor_id)", "Provider=MSDataShape;DSN=pubs;Integrated Security=SSPI;"
以下是持久保存的 Recordset 的 XML 格式:
<xml xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:rs="urn:schemas-microsoft-com:rowset"
xmlns:z="#RowsetSchema">
<s:Schema id="RowsetSchema">
<s:ElementType name="row" content="eltOnly" rs:updatable="true">
<s:AttributeType name="stor_id" rs:number="1"
rs:writeunknown="true">
<s:datatype dt:type="string" dt:maxLength="4"
rs:fixedlength="true" rs:maybenull="false"/>
</s:AttributeType>
<s:AttributeType name="stor_name" rs:number="2" rs:nullable="true"
rs:writeunknown="true">
<s:datatype dt:type="string" dt:maxLength="40"/>
</s:AttributeType>
<s:AttributeType name="state" rs:number="3" rs:nullable="true"
rs:writeunknown="true">
<s:datatype dt:type="string" dt:maxLength="2"
rs:fixedlength="true"/>
</s:AttributeType>
<s:ElementType name="rsSales" content="eltOnly"
rs:updatable="true" rs:relation="010000000100000000000000">
<s:AttributeType name="stor_id" rs:number="1"
rs:writeunknown="true">
<s:datatype dt:type="string" dt:maxLength="4"
rs:fixedlength="true" rs:maybenull="false"/>
</s:AttributeType>
<s:AttributeType name="ord_num" rs:number="2"
rs:writeunknown="true">
<s:datatype dt:type="string" dt:maxLength="20"
rs:maybenull="false"/>
</s:AttributeType>
<s:AttributeType name="ord_date" rs:number="3"
rs:writeunknown="true">
<s:datatype dt:type="dateTime" dt:maxLength="16"
rs:scale="3" rs:precision="23" rs:fixedlength="true"
rs:maybenull="false"/>
</s:AttributeType>
<s:AttributeType name="qty" rs:number="4" rs:writeunknown="true">
<s:datatype dt:type="i2" dt:maxLength="2" rs:precision="5"
rs:fixedlength="true" rs:maybenull="false"/>
</s:AttributeType>
<s:extends type="rs:rowbase"/>
</s:ElementType>
<s:extends type="rs:rowbase"/>
</s:ElementType>
</s:Schema>
<rs:data>
<z:row stor_id="6380" stor_name="Eric the Read Books" state="WA">
<rsSales stor_id="6380" ord_num="6871"
ord_date="1994-09-14T00:00:00" qty="5"/>
<rsSales stor_id="6380" ord_num="722a"
ord_date="1994-09-13T00:00:00" qty="3"/>
</z:row>
<z:row stor_id="7066" stor_name="Barnum's" state="CA">
<rsSales stor_id="7066" ord_num="A2976"
ord_date="1993-05-24T00:00:00" qty="50"/>
<rsSales stor_id="7066" ord_num="QA7442.3"
ord_date="1994-09-13T00:00:00" qty="75"/>
</z:row>
<z:row stor_id="7067" stor_name="News & Brews" state="CA">
<rsSales stor_id="7067" ord_num="D4482"
ord_date="1994-09-14T00:00:00" qty="10"/>
<rsSales stor_id="7067" ord_num="P2121"
ord_date="1992-06-15T00:00:00" qty="40"/>
<rsSales stor_id="7067" ord_num="P2121"
ord_date="1992-06-15T00:00:00" qty="20"/>
<rsSales stor_id="7067" ord_num="P2121"
ord_date="1992-06-15T00:00:00" qty="20"/>
</z:row>
</rs:data>
</xml>
以这种方式持久保存父 Recordset 时,其列的确切顺序并不明显。 父级中的任何字段都可能包含子 Recordset。 持久性提供程序首先将所有标量列持久保存为属性,然后将所有子 Recordset“列”持久保存为父行的子元素。 可通过查看 Recordset 的架构定义来获得父 Recordset 中该字段的序号位置。 每个字段都有一个 OLE DB 属性 rs:number,该属性是在包含该字段序号的 Recordset 架构命名空间中定义的。
子 Recordset 中所有字段的名称都加上了包含此子级的父 Recordset 中的字段名称。 这是为了确保当父 Recordset 和子 Recordset 都包含从两个不同的表中获得但被单独命名的字段时没有名称冲突。
将分层 Recordset 保存为 XML 格式时,应注意 ADO 中的以下限制:
如果分层 Recordset 具有挂起的更新,它将无法持久保存为 XML 格式。
使用参数化 shape 命令创建的分层 Recordset 无法持久保存(采用 XML 或 ADTG 格式)。
ADO 当前将父 Recordset 和子 Recordset 之间的关系保存为二进制大型对象 (BLOB)。 用于描述这种关系的 XML 标记尚未在行集架构命名空间中定义。
保存分层 Recordset 时,所有子 Recordset 都会随之保存。 如果当前的 Recordset 是另一个 Recordset 的子项,则不会保存其父项。 而是保存构成当前 Recordset 的子树的所有 Recordset。
以 XML 持久保存格式重新打开分层 Recordset 时,必须注意以下限制:
如果子记录包含的记录没有对应的父记录,则这些行不会写为分层 Recordset 的 XML 表示形式。 因此,从持久保存位置重新打开 Recordset 时,这些行将丢失。
如果子记录引用了多个父记录,则在重新打开 Recordset 时,子 Recordset 可能包含重复的记录。 但是,只有用户直接使用底层子行集时,这些重复项才可见。 如果使用段导航子 Recordset(这是通过 ADO 导航的唯一方法),则重复项不可见。