Skip to main content
Announcements
Live today at 11 AM ET. Get your questions about Qlik Connect answered, or just listen in. SIGN UP NOW
cancel
Showing results for 
Search instead for 
Did you mean: 
Thiago_Justen_

Extraindo campos de tags XML

Srs,

Estou com uma dúvida acerca de qual seria a melhor solução para a minha questão que segue:

Tenho um app que captura os xml's de notas fiscais de abastecimento e os "traduz" conforme script abaixo:

LOAD "XML",

TextBetween(XML,'KM:','.') as [NFe Abast - KM],

        TextBetween(XML,'PLACA:','KM:') as [NFe Abast - Placa],

        TextBetween(XML,'<chNFe>','</chNFe>') as [NFe Abast - Chave de Acesso],

        TextBetween(XML,'<vUnCom>','</vUnCom>') as [NFe Abast - Valor Unitario],

        len(TextBetween(XML,'<vUnCom>','</vUnCom>'))    as [Nfe Abast - Un. Medida],

        TextBetween(XML,'<vProd>','</vProd>') as [NFe Abast - Valor Total],

        TextBetween(XML,'<uCom>','</uCom>') as [NFe Abast - Un Medida],

        TextBetween(XML,'<xProd>','</xProd>') as [NFe Abast - Produto],

        TextBetween(XML,'<nNF>','</nNF>') as [NFe Abast - Numero],

        TextBetween(XML,'<xNome>','</xNome>') as [NFe Abast - Emitente Razao Social],

        TextBetween(XML,'<xFant>','</xFant>') as [NFe Abast - Emitente Nome Fantasia],

        TextBetween(XML,'<qCom>','</qCom>') as [NFe Abast - Quantidade],

        date(SubField(TextBetween(XML,'<dhEmi>','</dhEmi>'),'T',1)) as [NFe Abast - Data Emissao],

        Year((SubField(TextBetween(XML,'<dhEmi>','</dhEmi>'),'T',1))) as [NFe Abast - Ano Emissao],

        Month((SubField(TextBetween(XML,'<dhEmi>','</dhEmi>'),'T',1))) as [NFe Abast - Mes Emissao],

        Day((SubField(TextBetween(XML,'<dhEmi>','</dhEmi>'),'T',1))) as [NFe Abast - Dia Emissao],

        Time(SubField(SubField(TextBetween(XML,'<dhEmi>','</dhEmi>'),'T',2),'-',1),'hh:mm') as [NFe Abast - Hora Emissao],

        TextBetween(XML,'<xMotivo>','</xMotivo>') as [NFe Abast - Status]

FROM [lib://CARGA/NOTAS_ABASTECIMENTO.qvd](qvd);

Até aí tudo funciona "de boa" se, e somente se, a nota contiver  apenas um item (o que ocorre em 99% dos casos que temos). Esse 1% é que me arrebenta...

Vejam como o xml da NF vem quando há mais de um item:

item 1.PNG

item 2.PNG

Eis então minha questão:

Como fazer a leitura desses dois itens, considerando que as tags que utilizo são as mesmas nos dois itens?

cleveranjos‌, afurtado‌, stalwar1

Abs e Sucesso!

Thiago Justen Teixeira Gonçalves
Farol BI
WhatsApp: 24 98152-1675
Skype: justen.thiago
Labels (1)
1 Solution

Accepted Solutions
pablolabbe
Luminary Alumni
Luminary Alumni

Thiago,

  Achei sua dúvida desafiadora e resolvi testar algo. Bom cheguei neste load que talvez resolva seu problema:

  Para exemplificar gravei o conteudo dos 2 xmls enviados dentro de uma planilha excel para simular o banco de dados.

  Ela tem duas linhas e dentro da celula eu colei os XML. (a planilha exemplo está anexada a resposta)

  Para resolver o problema combinei a função TextBetween com a dupla (while & iterno) para criar um laço que se repete a cada linha tantas vezes for encontrada a tag </det> , isso determina o numero de itens de uma nf.

  O comando while cria uma linha para cada ocorrência da tag </det> desde que seja menor que o total de ocorrências encontradas (resultado do substringcount).

  Essa dica vale uns 10.000 pontos aqui na comunidade.  Hahahahahaha..

  Tai o script.

LOAD

     Registro,

     //cabeçalho NF

     TextBetween(XML,'KM:','.') as [NFe Abast - KM],

     TextBetween(XML,'PLACA:','KM:') as [NFe Abast - Placa],

     TextBetween(XML,'<chNFe>','</chNFe>') as [NFe Abast - Chave de Acesso],

     TextBetween(XML,'<vUnCom>','</vUnCom>') as [NFe Abast - Valor Unitario],

     len(TextBetween(XML,'<vUnCom>','</vUnCom>'))    as [Nfe Abast - Un. Medida],

     date(SubField(TextBetween(XML,'<dhEmi>','</dhEmi>'),'T',1)) as [NFe Abast - Data Emissao],

     Year((SubField(TextBetween(XML,'<dhEmi>','</dhEmi>'),'T',1))) as [NFe Abast - Ano Emissao],

     Month((SubField(TextBetween(XML,'<dhEmi>','</dhEmi>'),'T',1))) as [NFe Abast - Mes Emissao],

     Day((SubField(TextBetween(XML,'<dhEmi>','</dhEmi>'),'T',1))) as [NFe Abast - Dia Emissao],

     Time(SubField(SubField(TextBetween(XML,'<dhEmi>','</dhEmi>'),'T',2),'-',1),'hh:mm') as [NFe Abast - Hora Emissao],

     TextBetween(XML,'<xMotivo>','</xMotivo>') as [NFe Abast - Status],

     TextBetween(XML,'<nNF>','</nNF>') as [NFe Abast - Numero],

     TextBetween(XML,'<xNome>','</xNome>') as [NFe Abast - Emitente Razao Social],

     TextBetween(XML,'<xFant>','</xFant>') as [NFe Abast - Emitente Nome Fantasia],

     //itens NF  

     TextBetween(det_XML,'<vProd>','</vProd>') as [NFe Abast - Valor Total],

     TextBetween(det_XML,'<uCom>','</uCom>') as [NFe Abast - Un Medida],

     TextBetween(det_XML,'<xProd>','</xProd>') as [NFe Abast - Produto],

     TextBetween(det_XML,'<qCom>','</qCom>') as [NFe Abast - Quantidade];

LOAD Registro,

     XML,

     TextBetween(XML,'<det nItem','</det>',iterno()) as det_XML

FROM

[Dados XML.xlsx]

(ooxml, embedded labels, table is Planilha1)

while iterno() <= SubStringCount(XML,'det nItem') ;

Por isso que eu adoro script de Qlik !!!!!

Abraço,

Pablo

View solution in original post

21 Replies
afurtado
Partner Ambassador/MVP
Partner Ambassador/MVP

Thiago,

tens algum XML de exemplo?  

furtado@farolbi.com.br
pablolabbe
Luminary Alumni
Luminary Alumni

Thiago,

  Se você estivesse lendo diretamente o arquivo XML, o proprio Qlik iria gerar o script necessário para extrair os itens de detalhe da nfe, mas como está lendo de um campo, ai complicou.

  Talvez o uso do subfield te ajude a gerar uma linha para cada ocorrencia da string  "<det nItem="

https://help.qlik.com/pt-BR/qlikview/12.1/Subsystems/Client/Content/Scripting/StringFunctions/SubFie...

Thiago_Justen_
Author

Tá na mão mestre!

Thiago Justen Teixeira Gonçalves
Farol BI
WhatsApp: 24 98152-1675
Skype: justen.thiago
Thiago_Justen_
Author

Pois é Pablo. Nesse caso, meu ERP armazena todos os arquivos xml em uma tabela da qual eu os extraio e os salvo num qvd.

Thiago Justen Teixeira Gonçalves
Farol BI
WhatsApp: 24 98152-1675
Skype: justen.thiago
Thiago_Justen_
Author

Up!

Thiago Justen Teixeira Gonçalves
Farol BI
WhatsApp: 24 98152-1675
Skype: justen.thiago
Thiago_Justen_
Author

Alguém?!?

Thiago Justen Teixeira Gonçalves
Farol BI
WhatsApp: 24 98152-1675
Skype: justen.thiago
Ricardo_Gerhard
Employee
Employee

Terias como fazer o acesso e ler diretamente do banco ao invés do XML?

Se não, poderia fazer um load tradicional e o não tradicional quando o tamanho do arquivo xml for superior ao tradicional . Apenas uma ideia, mas: pega a lista dos xmls do diretório, separa o que é normal e carrega, as exceções lê com a estrutura diferente.

Ricardo Gerhard
OEM Solution Architect
LATAM
Thiago_Justen_
Author

Ricardo, gostei da ideia porque sim, eu posso e faço a leitura diretamente do bd. Mas seria muito abuso se eu te pedisse pra me dar um exemplo prático no que se refere ao que você chama de load tradicional e não tradicional?

Para facilitar a exemplificação, disponho dois modelos de xml que tenho: um com apenas um item (talvez esse chamaríamos de tradicional) e outro com 2 itens (não tradicional).

Abs e muito obrigado desde já pelo tempo dispendido.

Thiago Justen Teixeira Gonçalves
Farol BI
WhatsApp: 24 98152-1675
Skype: justen.thiago
Anonymous
Not applicable

Bom dia Thiago,

Uma vez que está fazendo a extração para qvd, por que não fazer a extração para xml mesmo e desta forma simplifica a carga dos dados? Talvez seja uma saída para o problema.