Skip to main content
Announcements
Have questions about Qlik Connect? Join us live on April 10th, at 11 AM ET: 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.