Usuário com melhor resposta
como carregar um xml com relacionamentos sem chave primária?

Pergunta
-
olá galera
estou com uma dificuldade, preciso importar arquivos xml da nfse, porém não sei como selecionar os ítens de cada nota sem ter algum dado em comum no nó <NOTA> e <ITEM>, segue um modelo bem resumido do XML, ele é exportado por data de emissão, então existem várias notas num mesmo arquivo:
<?xml version="1.0" encoding="UTF-8"?> <NOTAS> <VERSAO>1.00</VERSAO> <NOTA> <NUMERO>192</NUMERO> <CNPJ>123456789</CNPJ> <DT_COMPETENCIA>2012-02-03</DT_COMPETENCIA> <DISCRIMINACAO>MEDIÇÃO DE SERVIÇOS REFERENTE FUNDAÇÃO E ALICERCES.</DISCRIMINACAO> <VL_SERVICO>1234.56</VL_SERVICO> <TOM_CPF_CNPJ>123456789</TOM_CPF_CNPJ> <TOM_RAZAO_SOCIAL>TESTE TESTE </TOM_RAZAO_SOCIAL> <LISTA_ITENS> <ITEM> <DESCRICAO>TESTE TESTE </DESCRICAO> <QT_ITEM>1.00000</QT_ITEM> <VL_UNITARIO>1234.56</VL_UNITARIO> <SN_ISS_TRIBUTAVEL>1</SN_ISS_TRIBUTAVEL> </ITEM> </LISTA_ITENS> </NOTA> <NOTA> <NUMERO>193</NUMERO> <CNPJ>123456789</CNPJ> <DT_COMPETENCIA>2012-02-03</DT_COMPETENCIA> <DISCRIMINACAO>MEDIÇÃO DE SERVIÇOS REFERENTE FUNDAÇÃO E ALICERCES.</DISCRIMINACAO> <VL_SERVICO>2469.12</VL_SERVICO> <TOM_CPF_CNPJ>123456789</TOM_CPF_CNPJ> <TOM_RAZAO_SOCIAL>TESTE TESTE </TOM_RAZAO_SOCIAL> <LISTA_ITENS> <ITEM> <DESCRICAO>TESTE TESTE </DESCRICAO> <QT_ITEM>1.00000</QT_ITEM> <VL_UNITARIO>1234.56</VL_UNITARIO> <SN_ISS_TRIBUTAVEL>1</SN_ISS_TRIBUTAVEL> </ITEM> <ITEM> <DESCRICAO>TESTE TESTE </DESCRICAO> <QT_ITEM>1.00000</QT_ITEM> <VL_UNITARIO>1234.56</VL_UNITARIO> <SN_ISS_TRIBUTAVEL>1</SN_ISS_TRIBUTAVEL> </ITEM> </LISTA_ITENS> </NOTA> <NOTA> <NUMERO>194</NUMERO> <CNPJ>123456789</CNPJ> <DT_COMPETENCIA>2012-02-03</DT_COMPETENCIA> <DISCRIMINACAO>MEDIÇÃO DE SERVIÇOS REFERENTE FUNDAÇÃO E ALICERCES.</DISCRIMINACAO> <VL_SERVICO>1234.56</VL_SERVICO> <TOM_CPF_CNPJ>123456789</TOM_CPF_CNPJ> <TOM_RAZAO_SOCIAL>TESTE TESTE </TOM_RAZAO_SOCIAL> <LISTA_ITENS> <ITEM> <DESCRICAO>TESTE TESTE </DESCRICAO> <QT_ITEM>1.00000</QT_ITEM> <VL_UNITARIO>1234.56</VL_UNITARIO> <SN_ISS_TRIBUTAVEL>1</SN_ISS_TRIBUTAVEL> </ITEM> </LISTA_ITENS> </NOTA> </NOTAS>
a rotina q usei para abrir o xml foi:
xmlfile = XmlReader.Create(TextBox1.Text, New XmlReaderSettings()) ds.Clear() ds.ReadXml(xmlfile) DataGridView1.DataSource = ds.Tables("NOTA") DataGridView2.DataSource = ds.Tables("ITEM")
até aí abriu nas datagrids, uma é para a nota e outra para os itens, abriu na mesma ordem, porém fiz uma alteração neste xml da nota 192 contendo dois itens nela, como vou saber quem são e quantos são os ítens da nota 192?
Respostas
-
yae Paulo blza?
então consegui inserir os numeros das notas em cada ítem usando for each, de uma olhada, mas acho q fiz uma volta desnecessária q é a de carregar o arquivo xml 2 vezes, é pq aproveitei o código q havia implementado anteriormente
ds.Clear() xmlfile = XmlReader.Create(TextBox1.Text, New XmlReaderSettings()) ds.ReadXml(xmlfile) 'Cria uma tabela para inserir os ítens com o número da nota como chave estrangeira ds.Tables.Add("ITENSNOTA") With ds.Tables("ITENSNOTA") .Columns.Add("NUMERO") .Columns.Add("DESCRICAO") .Columns.Add("QT_ITEM") .Columns.Add("VL_UNITARIO") .Columns.Add("SN_ISS_TRIBUTAVEL") End With Dim arquivoXML As New XmlDocument arquivoXML.Load(TextBox1.Text) Dim NOTA As Xml.XmlNode Dim ITEM As Xml.XmlNode 'Itens For Each NOTA In arquivoXML.SelectNodes("NOTAS/NOTA") Dim NUMERO = NOTA.SelectSingleNode("NUMERO").InnerText MsgBox("qtd de itens = " & NOTA.LastChild.ChildNodes.Count) If NOTA.LastChild.ChildNodes.Count > 1 Then For Each ITEM In NOTA.SelectNodes("LISTA_ITENS/ITEM") With ds.Tables("ITENSNOTA") .Rows.Add(NUMERO, ITEM.SelectSingleNode("DESCRICAO").InnerText, ITEM.SelectSingleNode("QT_ITEM").InnerText, ITEM.SelectSingleNode("VL_UNITARIO").InnerText, ITEM.SelectSingleNode("SN_ISS_TRIBUTAVEL").InnerText) End With Next Else With ds.Tables("ITENSNOTA") .Rows.Add(NUMERO, NOTA.LastChild.LastChild.SelectSingleNode("DESCRICAO").InnerText, NOTA.LastChild.LastChild.SelectSingleNode("QT_ITEM").InnerText, NOTA.LastChild.LastChild.SelectSingleNode("VL_UNITARIO").InnerText, NOTA.LastChild.LastChild.SelectSingleNode("SN_ISS_TRIBUTAVEL").InnerText) End With End If Next DataGridView1.DataSource = ds.Tables("NOTA") DataGridView2.DataSource = ds.Tables("ITENSNOTA")
vlw
muito obrigado pela dica!
- Editado andremedeiross segunda-feira, 27 de fevereiro de 2012 17:27
- Marcado como Resposta andremedeiross segunda-feira, 27 de fevereiro de 2012 17:31
Todas as Respostas
-
Eu te faço a mesma pergunta: como saber o "que é de que" se você não tem nada em comun? Tente conversar com a pessoa responsável por gerar o XML se existe alguma lógica.
Paulo César Viana
.NET Developer
MCC - Microsoft Community Contributor
MCP - Microsoft Certified Professional
MCTS - Microsoft Certified Technology Especialist
--
Marque as respostas e contribua para uma melhora no fórum. -
realmente carregando o xml desta forma não da para encontrar nada em comum, será que existe alguma forma de carregar um nó por vez? pois assim eu saberia quais os ítens de cada nota.
A minha intenção é importar o xml para um banco de dados, então se for possível carregar um nó <NOTA> por vez inclusive os nós filhos <ITEM> poderia importar tranquilamente os dados que preciso, na verdade não preciso de importar a nota inteira para o sistema, apenas o número da nota, os impostos, os ítens e o valor de cada ítem com os respectivos impostos de cada ítem.
-
Carregue ele apenas de uma vez, com você já está fazendo. Para acessar cada "nota" você vai usar um foreach normal.
Paulo César Viana
.NET Developer
MCC - Microsoft Community Contributor
MCP - Microsoft Certified Professional
MCTS - Microsoft Certified Technology Especialist
--
Marque as respostas e contribua para uma melhora no fórum. -
-
yae Paulo blza?
então consegui inserir os numeros das notas em cada ítem usando for each, de uma olhada, mas acho q fiz uma volta desnecessária q é a de carregar o arquivo xml 2 vezes, é pq aproveitei o código q havia implementado anteriormente
ds.Clear() xmlfile = XmlReader.Create(TextBox1.Text, New XmlReaderSettings()) ds.ReadXml(xmlfile) 'Cria uma tabela para inserir os ítens com o número da nota como chave estrangeira ds.Tables.Add("ITENSNOTA") With ds.Tables("ITENSNOTA") .Columns.Add("NUMERO") .Columns.Add("DESCRICAO") .Columns.Add("QT_ITEM") .Columns.Add("VL_UNITARIO") .Columns.Add("SN_ISS_TRIBUTAVEL") End With Dim arquivoXML As New XmlDocument arquivoXML.Load(TextBox1.Text) Dim NOTA As Xml.XmlNode Dim ITEM As Xml.XmlNode 'Itens For Each NOTA In arquivoXML.SelectNodes("NOTAS/NOTA") Dim NUMERO = NOTA.SelectSingleNode("NUMERO").InnerText MsgBox("qtd de itens = " & NOTA.LastChild.ChildNodes.Count) If NOTA.LastChild.ChildNodes.Count > 1 Then For Each ITEM In NOTA.SelectNodes("LISTA_ITENS/ITEM") With ds.Tables("ITENSNOTA") .Rows.Add(NUMERO, ITEM.SelectSingleNode("DESCRICAO").InnerText, ITEM.SelectSingleNode("QT_ITEM").InnerText, ITEM.SelectSingleNode("VL_UNITARIO").InnerText, ITEM.SelectSingleNode("SN_ISS_TRIBUTAVEL").InnerText) End With Next Else With ds.Tables("ITENSNOTA") .Rows.Add(NUMERO, NOTA.LastChild.LastChild.SelectSingleNode("DESCRICAO").InnerText, NOTA.LastChild.LastChild.SelectSingleNode("QT_ITEM").InnerText, NOTA.LastChild.LastChild.SelectSingleNode("VL_UNITARIO").InnerText, NOTA.LastChild.LastChild.SelectSingleNode("SN_ISS_TRIBUTAVEL").InnerText) End With End If Next DataGridView1.DataSource = ds.Tables("NOTA") DataGridView2.DataSource = ds.Tables("ITENSNOTA")
vlw
muito obrigado pela dica!
- Editado andremedeiross segunda-feira, 27 de fevereiro de 2012 17:27
- Marcado como Resposta andremedeiross segunda-feira, 27 de fevereiro de 2012 17:31
-
Melhorei o código!
agora eu só separo os campos que realmente preciso, e uso o dataset apenas para armazenar os dados já tratados, assim posso criar uma function do tipo dataset para retornar um dataset toda vez que for chamada
para quem interessar o código é este:
Dim ds As New DataSet 'Tabela referente aos dados principais da nota fiscal ds.Tables.Add("NOTAFISCAL") With ds.Tables("NOTAFISCAL").Columns .Add("NUMERO") .Add("CNPJ") .Add("INSCRICAO_MUNICIPAL") .Add("CD_VERIFICACAO") .Add("CD_STATUS") .Add("DT_CANCELAMENTO") .Add("DT_COMPETENCIA") .Add("DISCRIMINACAO") .Add("VL_SERVICO") .Add("VL_DEDUCAO") .Add("VL_PIS") .Add("VL_COFINS") .Add("VL_INSS") .Add("VL_IR") .Add("VL_CSLL") .Add("SN_ISS_RETIDO") .Add("VL_ISS") .Add("VL_ISS_RETIDO") .Add("VL_OUTRAS_RETENCOES") .Add("VL_BASE_CALCULO") .Add("VL_ALIQUOTA") .Add("VL_LIQUIDO_NFSE") .Add("VL_DESCONTO_INCONDICIONADO") .Add("VL_DESCONTO_CONDICIONADO") .Add("AL_PIS") .Add("AL_COFINS") .Add("AL_INSS") .Add("AL_IR") .Add("AL_CSLL") .Add("TOM_CPF_CNPJ") .Add("TOM_RAZAO_SOCIAL") .Add("TOM_ENDERECO") .Add("TOM_ENDERECO_NUMERO") .Add("TOM_ENDERECO_COMPLEMENTO") .Add("TOM_ENDERECO_BAIRRO") .Add("TOM_ENDERECO_UF") .Add("TOM_ENDERECO_CEP") .Add("TOM_TELEFONE") .Add("TOM_EMAIL") End With 'Cria uma tabela para inserir os ítens com o número da nota como chave estrangeira ds.Tables.Add("ITENSNOTA") With ds.Tables("ITENSNOTA").Columns .Add("NUMERO") .Add("DESCRICAO") .Add("QT_ITEM") .Add("VL_UNITARIO") .Add("SN_ISS_TRIBUTAVEL") End With 'Carrega o arquivo XML Dim arquivoXML As New XmlDocument arquivoXML.Load(TextBox1.Text) Dim NOTA As Xml.XmlNode Dim ITEM As Xml.XmlNode Dim i As Integer = 0 'Separando os dados da notafiscal For Each NOTA In arquivoXML.SelectNodes("NOTAS/NOTA") Dim NUMERO As Integer = NOTA.SelectSingleNode("NUMERO").InnerText 'Insere os dados principais da NOTAFISCAL With ds.Tables("NOTAFISCAL") .Rows.Add() .Rows(i).Item("NUMERO") = NUMERO For j As Integer = 0 To ds.Tables("NOTAFISCAL").Columns.Count - 1 .Rows(i).Item(j) = NOTA.SelectSingleNode(.Columns(j).ColumnName).InnerText Next End With 'Incrementa a linha para uma nova nota fiscal i += 1 'Insere os ítens da nota fiscal na tabela ITENSNOTA If NOTA.LastChild.ChildNodes.Count > 1 Then For Each ITEM In NOTA.SelectNodes("LISTA_ITENS/ITEM") With ds.Tables("ITENSNOTA") .Rows.Add(NUMERO, ITEM.SelectSingleNode("DESCRICAO").InnerText, ITEM.SelectSingleNode("QT_ITEM").InnerText, ITEM.SelectSingleNode("VL_UNITARIO").InnerText, ITEM.SelectSingleNode("SN_ISS_TRIBUTAVEL").InnerText) End With Next Else With ds.Tables("ITENSNOTA") .Rows.Add(NUMERO, NOTA.LastChild.LastChild.SelectSingleNode("DESCRICAO").InnerText, NOTA.LastChild.LastChild.SelectSingleNode("QT_ITEM").InnerText, NOTA.LastChild.LastChild.SelectSingleNode("VL_UNITARIO").InnerText, NOTA.LastChild.LastChild.SelectSingleNode("SN_ISS_TRIBUTAVEL").InnerText) End With End If Next 'Resultado DataGridView1.DataSource = ds.Tables("NOTAFISCAL") DataGridView2.DataSource = ds.Tables("ITENSNOTA")
Caso possam melhorar o código ou alguma sugestão gostaria de ser reportado!
vlw pessoal