Inquiridor
Carga de XML em DataGrid para busca, ordenação, filtro e paginação.

Pergunta
-
Boa tarde,
Possuo o XML e o XSD abaixo.
Carrego o XML em um Dataset, mas não é possível exibir toda a estrutura em um DataGrid por não se tratar de um XML sequencial.
Preciso disponibilizar uma busca como, por exemplo: Listar todos os registros DOC que tenham a data de movimento igual a 2006-06-02.
Alguém tem uma dica sobre um método para fazer isso?
Grato,
Carlos.
[
<?xml version="1.0" ?>
<SPB xmlns="http://tempuri.org/teste.xsd">
<DOC>
<BCMSG>
<Grupo_EmissorMsg>
<TpIdentdEmissor>P</TpIdentdEmissor>
<IdentdEmissor>0001</IdentdEmissor>
</Grupo_EmissorMsg>
<Grupo_DestinatarioMsg>
<TpIdentdDestinatario>P</TpIdentdDestinatario>
<IdentdDestinatario>000</IdentdDestinatario>
</Grupo_DestinatarioMsg>
<DomSist>ABC01</DomSist>
<NUOp>00033</NUOp>
</BCMSG>
<SISMSG>
<GENAvisArquivoDisp>
<CodMsg>MEUCOD</CodMsg>
<ISPBEmissor>444</ISPBEmissor>
<ISPBDestinatario>555</ISPBDestinatario>
<NumCtrlIF>66</NumCtrlIF>
<TpTransm>E</TpTransm>
<NomArq>NOMEA7</NomArq>
<IdentdArq>IDENTIFICACAO</IdentdArq>
<Hist>MY history...</Hist>
<DtHrPart>2006-06-01T20:57:17</DtHrPart>
<DtMovto>2006-06-02</DtMovto>
</GENAvisArquivoDisp>
</SISMSG>
<USERMSG>mensagem do usuario</USERMSG>
</DOC>Gerei o seguinte código para o arquivo XSD:
<?xml version="1.0" ?>
<xs:schema id="ABC" targetNamespace="http://tempuri.org/teste.xsd" xmlns:mstns="http://tempuri.org/teste.xsd"
xmlns="http://tempuri.org/teste.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"
attributeFormDefault="qualified" elementFormDefault="qualified">
<xs:element name="SPB" msdata:IsDataSet="true" msdata:Locale="pt-BR" msdata:EnforceConstraints="False">
<xs:complexType>
<xs:choice maxOccurs="unbounded">
<xs:element name="DOC">
<xs:complexType>
<xs:sequence>
<xs:element name="USERMSG" type="xs:string" minOccurs="0" />
<xs:element name="BCMSG" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="DomSist" type="xs:string" minOccurs="0" />
<xs:element name="NUOp" type="xs:string" minOccurs="0" />
<xs:element name="Grupo_EmissorMsg" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="TpIdentdEmissor" type="xs:string" minOccurs="0" />
<xs:element name="IdentdEmissor" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Grupo_DestinatarioMsg" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="TpIdentdDestinatario" type="xs:string" minOccurs="0" />
<xs:element name="IdentdDestinatario" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="SISMSG" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="GENAvisArquivoDisp" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="CodMsg" type="xs:string" minOccurs="0" />
<xs:element name="ISPBEmissor" type="xs:string" minOccurs="0" />
<xs:element name="ISPBDestinatario" type="xs:string" minOccurs="0" />
<xs:element name="NumCtrlIF" type="xs:string" minOccurs="0" />
<xs:element name="TpTransm" type="xs:string" minOccurs="0" />
<xs:element name="NomArq" type="xs:string" minOccurs="0" />
<xs:element name="IdentdArq" type="xs:string" minOccurs="0" />
<xs:element name="Hist" type="xs:string" minOccurs="0" />
<xs:element name="DtHrPart" type="xs:string" minOccurs="0" />
<xs:element name="DtMovto" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
]
Todas as Respostas
-
Olá Carlos,
O documento XML que você apresentou não parece seguir um padrão tabular (linhas e colunas). Isso dificulta o uso dele dentro de DataSets e, especialmente, com DataGrids.
Uma idéia seria transformar esse XML para um outro formato mais tabular e, aproveitando a fase de transformação, já poderia ser feita a filtragem pela data de movimento neste momento. Fiz um pequeno exemplo adaptado a partir do modelo do seu documento XML. O documento é transformado através de um template XSL e dá origem a um outro documento XML, este num formato mais tabular. Após, o documento XML resultante da transformação é carregado em um DataSet e, finalmente, ligado a um controle DataGrid.
Veja que esse modelo permite que você opte por alternativas diferentes. Uma coisa que você poderia fazer, por exemplo, é deixar para filtrar pela data somente ápós a carga do XML dentro do DataSet, usando o método Select da classe DataTable. Aí fica ao seu critério e necessidades.
O código abaixo é um exemplo simples que dá a idéia de como seria o documento de transformação XSL:
<?
xml version="1.0" encoding="utf-8"?><
xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:n="http://tempuri.org/teste.xsd"><
xsl:output method="xml"/><
xsl:param name="dataMovimento" select="'2006-06-06'"/><
xsl:template match="/"><
SPB><
xsl:apply-templates select="/n:SPB/n:DOC" /></
SPB></
xsl:template><
xsl:template match="n:SPB/n:DOC"><
xsl:apply-templates select=".//n:DtMovto[ . = $dataMovimento]" /></
xsl:template><
xsl:template match="n:DtMovto"><
DOC><
DtMovto><
xsl:value-of select="."/></
DtMovto><
CodMsg><
xsl:value-of select="../n:CodMsg"/></
CodMsg><
NomArq><
xsl:value-of select="../n:NomArq"/></
NomArq></
DOC></
xsl:template></
xsl:stylesheet>Um exemplo de documento resultante da transformação seria o seguinte:
<?
xml version="1.0" encoding="utf-8"?><
SPB xmlns:n="http://tempuri.org/teste.xsd"><
DOC><
DtMovto>2006-06-06</DtMovto><
CodMsg>MEUCOD</CodMsg><
NomArq>NOMEA7</NomArq></
DOC></
SPB>Este seria o XML a ser carregado no DataSet. Ele seria entendido com uma estrutura tabular (com linhas e colunas) e seria carregado de forma mais adequada no DataGrid.
O código do programa que faria a transformação e a carga do documento XML resultante em um DataSet é mostrado a seguir:
string xmlFileLocation = Path.Combine(Server.MapPath("~"), "Xml/Teste.Xml"); string xslFileLocation = Path.Combine(Server.MapPath("~"), "Xml/TransformaXmlHierarquicoEmTabular.xsl"); XPathDocument doc = new XPathDocument(xmlFileLocation); XslCompiledTransform xsl = new XslCompiledTransform();xsl.Load(xslFileLocation);
XsltArgumentList xslArgumentList = new XsltArgumentList();xslArgumentList.AddParam(
"dataMovimento", "", DateTime.Now.ToString("yyyy-MM-dd")); StringWriter sw = new StringWriter();xsl.Transform(doc, xslArgumentList, sw);
sw.Close();
DataSet ds = new DataSet("Spb");ds.ReadXml(
new StringReader(sw.ToString()));_dataGrid.DataSource = ds;
_dataGrid.DataBind();
Espero que ajude!Um abraço!
-----
Fabio Vazquez [C# MVP]
Blog: http://www.phidelis.com.br/blogs/fabiovazquez
-
Nunca é tarde para agradecer...
Muito obrigado Fabio!
Abraços,
Carlos Camacho.
www.camachojunior.com.br