Conjuntos de registros hierárquicos em XML
O ADO permite a persistência de objetos Recordset hierárquicos em XML. Com objetos Recordset hierárquicos, o valor de um campo no Recordset pai é outro Recordset. Esses campos são representados como elementos filho no fluxo XML em vez de um atributo.
Comentários
O seguinte exemplo demonstra esse caso:
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;"
Veja abaixo o formato XML do Recordset persistente:
<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>
A ordem exata das colunas no Recordset pai não é óbvia quando ela é persistente dessa maneira. Qualquer campo no pai pode conter um Recordset filho. O Provedor de Persistência persiste todas as colunas escalares primeiro como atributos e, em seguida, persiste todas as "colunas" do Recordset filho como elementos filho da linha pai. A posição ordinal do campo no Recordset pai pode ser obtida com o exame da definição de esquema do Recordset. Cada campo tem uma propriedade OLE DB, rs:number, definida no namespace do esquema Recordset que contém o número ordinal desse campo.
Os nomes de todos os campos no Recordset filho são concatenados com o nome do campo no Recordset pai que contém esse filho. Isso é para garantir que não haja conflitos de nome nos casos em que os Recordsets pai e filho contenham um campo obtido de duas tabelas diferentes, mas com o mesmo nome.
Ao salvar Recordsets hierárquicos em XML, você deve estar ciente das seguintes restrições no ADO:
Um Recordset hierárquico com atualizações pendentes não pode ser persistido em XML.
Não é possível persistir um Recordset hierárquico criado com um comando de forma parametrizada (no formato XML ou ADTG).
Atualmente, o ADO salva a relação entre os Recordsets pai e filho como um BLOB (objeto binário grande). As marcas XML para descrever essa relação ainda não foram definidas no namespace do esquema de conjunto de linhas.
Quando um Recordset hierárquico é salvo, todos os Recordsets filho são salvos junto com ele. Se o Recordset atual for um filho de outro Recordset, seu pai não será salvo. Todos os Recordsets filho que formam a subárvore do Recordset atual são salvos.
Quando um Recordset hierárquico é reaberto de seu formato persistente XML, você precisa estar ciente das seguintes limitações:
Se o registro filho contiver registros para os quais não há registros pai correspondentes, essas linhas não serão gravadas na representação XML do Recordset hierárquico. Assim, essas linhas serão perdidas quando o Recordset for reaberto de seu local persistente.
Se um registro filho tiver referências a mais de um registro pai, na reabertura do Recordset, o Recordset filho poderá conter registros duplicados. No entanto, essas duplicatas só ficarão visíveis se o usuário trabalhar diretamente com o conjunto de linhas filho subjacente. Se um capítulo for usado para navegar pelo Recordset filho (essa é a única maneira de navegar pelo ADO), as duplicatas não estarão visíveis.