XML 中的层次记录集

适用于:Access 2013、Office 2013

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;UID=MyUserId;PWD=MyPassword;" 

下面是持久化的 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 。 Persistence Provider 首先将所有标量列作为属性持久化出来,然后将所有子 Recordset 的"列"作为父行的子元素持久化出来。 通过查看 Recordset 的架构定义,可以获得父 Recordset 中字段的序号位置。 每个字段都有 OLE DB 属性 rs:number ,该属性是在包含该字段序号的 Recordset 架构命名空间中定义的。

Recordset 中所有字段的名称都与包含该子对象的父 Recordset 中的字段的名称串联在一起。 这是为了确保万一父和子 Recordset 都包含从两个不同表获得的同名字段时,不会有名称冲突。

将分层 Recordset 保存到 XML 中时,应当知道 ADO 中的以下限制:

  • 具有挂起更新的分层 Recordset 无法持久化到 XML 中。

  • 以参数化 Shape 命令创建的分层 Recordset 无法持久化(以 XML 或 ADTG 格式)。

  • ADO 目前将父和子 Recordset 之间的关系作为二进制大型对象 (BLOB) 进行保存。 在行集架构命名空间中,尚未定义用于描述此关系的 XML 标记。

  • 保存分层 Recordset 时,所有子 Recordset 都将与它一起保存。 如果当前 Recordset 是另一个 Recordset 的子对象,则不保存它的父对象。 构成当前 Recordset 的子树的所有子 Recordset 都会保存。

从其 XML 持久化的格式重新打开分层 Recordset 时,必须知道以下限制:

  • 如果子记录包含的记录没有相应的父记录,则这些行不以分层 Recordset 的 XML 表示形式写出。 因此,从其持久化的位置重新打开 Recordset 时,将丢失这些行。

  • 如果子记录引用了多个父记录,则重新打开该 Recordset ,子 Recordset 可能包含重复记录。 但是,只有当用户直接处理基础子行集时,这些重复才是可见的。 如果用章节来导航子 Recordset (这是在 ADO 中导航的唯一方式),则重复是不可见的。