Jump to content

Ajuda com XML ANBIMA_4_01


afprospero
Ir para a Solução Solucionado por afprospero,

Postagens Recomendadas

Boa tarde a todos. Estou começando a trabalhar com PYthon,   estou aprendendo ainda a linguagem,  aqui na empresa e me deparei com um problema.

Tenho varios xmls em um diretório. Todos no padrão ANBIMA4_01 de posicao. Eu preciso ler todos os xmls e criar um arquivo unificado com os dados dos clientes e seus respectivos investimentos.

A estrutura é parecida com os xmls anexos. Lembrando que a seção HEADER sempre existirá nos xmls, as demais (titprivado e açoes que estão no xml exemplo) podem ou não estar no arquivo (existem mais umas 15 seções que podem estar no xml, dependendo do tipo de investimento)

Eu consegui abrir todos os xmls, consigo ler as seções, consigo validar se a seção existe ou não, mas não estou conseguindo gerar o loop para empilhar os ativos, repetindo os dados de header para cada item, como por exemplo abaixo:

nome_cli idade_cli nom_ativo cod_ativo valor_ativo tipo_ativo
ANDERSON DA SILVA 44 TITULO BANCO ABC 123456 6387999.86 titprivado
ANDERSON DA SILVA 44 ACAO ZE DELIVERY 159753 58423.57 acao
ANDERSON DA SILVA 44 TITULO BANCO BLABLA 9876544 3867750.54 titprivado
MANECO DE SOUZA 58 TITULO BANCO ABC 123456 6387999.86 titprivado
MANECO DE SOUZA 58 TITULO BANCO BLABLA 9876544 3867750.54 titprivado

Ja pesquisei na própria ANBIMA um leitor python para esse arquivo e não encontrei, então preciso montar esse para utiulizar aqui no trabalho para uma demanda que vai virar rotina. 

Agradeço muito se alguém puder me ajudar com isso e desculpem se for algo básico, mas como estou aprendendo ainda não consigo passar desse passo.

Grande abraço a todos.

TESTE_ANDERSON.xml TESTE_ANDERSON2.xml

Link to comment
Compartilhe em outros sites

  • Pessoal da TecnoSpeed

Olá @afprospero tudo bem ? 

Segue abaixo um script contendo o que precisa.

OBS:  Estou usando a biblioteca BeautifulSoup para leitura dos dados do XML, é muito usada para WebScraping (raspagem de dados de sites)

1° Passo: Importas as biblitoecas

import pandas as pd
import re
from bs4 import BeautifulSoup 
import os

2° Passo: Criar uma função para extrair os dados.

def get_dados_anbima(xml):
    
    df_registro = pd.DataFrame()
    
    header = xml.find('HEADER')
    for tipo in ['TITPRIVADO','ACOES']:
        
        # Percorrer pelos tipos obtendo os dados
        for dados_tipo in xml.find_all(tipo):
            registro = {
                'nome_cli' : header.NOME.getText(),
                'idade_cli' : header.IDADE.getText(),
                'nom_ativo' : dados_tipo.NOME.getText(),
                'cod_ativo' :  dados_tipo.CODIGO.getText() ,
                'valor_ativo' : dados_tipo.VALOR.getText(),
                'tipo_ativo' : tipo
            }

            # Adiciconar o registro ao DataFrame criado
            df_registro = df_registro.append(pd.DataFrame([registro]))
    return df_registro

3° Passo: Criar o LOOP para passar pelos arquivos e chamar a função

# Caminho da pasta
# Passar o diretorio dos XMLs
path = r'C:\Users\zThan\OneDrive\Documentos'

df = pd.DataFrame()

# Percorrer somente pelos arquivos .xml
for file in os.listdir(path):                  
    if re.search('xml', file):
      
        # Leitura do arquivo
        with open(file, 'r') as f: 
            data = f.read() 
        
        # Criar a variavel xml que contém o texto do arquivo xml
        xml = BeautifulSoup(data, "xml")
        
        # Chama a função criada e obtem os dados do arquivo.
        df = df.append(get_dados_anbima(xml))
        
        print(f'Arquivo: {file} - OK')
        
df = df.reset_index(drop = True)

Segue abaixo um print do resultado, com base nos 2 arquivos que você deixou na descrição.

image.png

Obs: Durante a execução do script ele printa alguns alertas, mas pode ignora-los, são só avisos de que a biblioteca vai mudar no futuro.

Espero que seja isso que esteja procurando, caso contrario estou a disposição para lhe ajudar. 👍

Link to comment
Compartilhe em outros sites

Oi @Thanael bom dia.

Obrigado pela ajuda meu jovem. Coloquei o código aqui e rodei. Não deu certo e apresentou a mensagem abaixo:

FileNotFoundError: [Errno 2] No such file or directory: 'Mapa_XML_Posicao_Carteira_Copia.xml'

Eu informei o meu diretório no lugar do que está no seu código. Ja reiniciei a maquina e não deu certo.

Outra coisa.... As seções do arquivo original não possuem o mesmo campo, como no arquivo de exemplo. Eu descaracterizei os dados de um arquivo e estou anexando novamente. As seções que são diferentes de HEADER são as das aplicações do cliente e preciso trazer alguns dados, por exemplo, para titprivado existem codativo, isin, dtinicial, valoraplicado ja na seção acoes os campos possuem outros nomes.  Isso acontece para todas seções. Cada seção do arquivo possui um nome especifico e eu irei informar quais deles quero trazer.

então com base nesse novo arquivo eu preciso trazer os dados abaixo, só para construir a lógica e depois eu replico:

header - cnpjcpf, codcart

titprivado - codativ (como cod_ativo), isin (como nom_ativo), valorfinddisp (como valor_ativo) e titprivado

termorv- cusip (como cod_ativo),  ativo (bon_ativo), valorfinanceiro (como valor_ativo) e termorv

As demais seções eu replico a solução com seus respectivos campos. 

No final eu preciso de um df com os dados destas 2 seções iguais ao resultado que você me mostrou e se possível, preciso salvar um xlsx com todos os resultados de todas as seções no formato de saída.

Desculpe meu pouco conhecimento, mas to corrento nos treinamentos para aprender.

Obrigado e se quiser me envie e-mail afprospero@yahoo.com.br

Mapa_XML_Posicao_Carteira_Copia.xml

Editado por afprospero
faltou mencionar a pessoa no comentário.
Link to comment
Compartilhe em outros sites

  • Pessoal da TecnoSpeed

Opa segue abaixo o código que necessita e o resultado.

import pandas as pd
import re
from bs4 import BeautifulSoup 
import os

def get_dados_anbima(xml):
    
    df_registro = pd.DataFrame()

    header = xml.find('header')

    # Percorrer pelos tipos obtendo os dados
    for titprivado in xml.find_all('titprivado'):
        registro = {
            'cnpjcpf' : header.cnpjcpf.getText(),
            'codcart' : header.codcart.getText(),
            'cod_ativo' : titprivado.codativo.getText() if titprivado.codativo else None,
            'nom_ativo' : titprivado.isin.getText() if titprivado.isin else None,
            'valor_ativo' : titprivado.valorfinddisp.getText() if titprivado.valorfinddisp else None,
            'tipo_ativo': 'titprivado'
        }
        # Adiciconar o registro ao DataFrame criado
        df_registro = df_registro.append(pd.DataFrame([registro]))

    # Percorrer pelos tipos obtendo os dados
    for termorv in xml.find_all('termorv'):
        registro = {
            'cnpjcpf' : header.cnpjcpf.getText(),
            'codcart' : header.codcart.getText(),
            'cod_ativo' : termorv.codativ.getText() if termorv.codativ else None,
            'nom_ativo' : termorv.isin.getText() if termorv.isin else None,
            'valor_ativo' : termorv.valorfinanceiro .getText() if termorv.valorfinanceiro  else None,
            'tipo_ativo': 'termorv'
        }
        # Adiciconar o registro ao DataFrame criado
        df_registro = df_registro.append(pd.DataFrame([registro])) 

    return df_registro

# INICIO DO CODIGO DE FATO
  
# Caminho da pasta - Passar o diretorio dos XMLs
path = r'C:\Users\thanael.butewicz\Documents'

df = pd.DataFrame()

# Percorrer somente pelos arquivos .xml
for file in os.listdir(path):                  
    if re.search('xml', file):
      
        # Leitura do arquivo
        with open(file, 'r') as f: 
            data = f.read() 
        
        # Criar a variavel xml que contém o texto do arquivo xml
        xml = BeautifulSoup(data.replace('',''), "xml")
        
        # Chama a função criada e obtem os dados do arquivo.
        df = df.append(get_dados_anbima(xml))
        
        print(f'Arquivo: {file} - OK')
        
df = df.reset_index(drop = True)

Captura de tela 2023-03-13 200526.png

Enfim espero que seja isso que precise, caso contrário estou a disposição ou pode me chamar no discord Thanael#0530 que posso separar um momento e lhe explicar o funcionamento do código e lhe ajudar diretamente compartilhando a tela ou conversando mesmo.

Link to comment
Compartilhe em outros sites

Olá @Thanael, entendi o código. ficou mto bom. E isso que eu preciso mesmo.

Copiei o seu código inteiro, para o Spyder Anaconda, e alterei seu diretório para o meu. (C:\Temp) e não executa. 

Da o erro "FileNotFoundError: [Errno 2] No such file or directory: 'Mapa_XML_Posicao_Carteira.xml'".

Ja tentei de tudo, mas não to conseguindo executar. Te add no Discord também.

Se puder me ajudar, te agradeço muito.

Valeu

Link to comment
Compartilhe em outros sites

  • 2 weeks later...
  • Solução

Pessoal, boa tarde.

Com a ajuda do @Thanael consegui finalizar o que eu precisava. Vou anexar aqui o projeto Py e caso alguém precise ja está pronto pra utilizar no Padrão Anbima 4.0 para Carteiras.

Eu utilizei o código que ele ajudou (fez tudo praticamente, rsrsrs) e copiei ele para cada uma das seções de  investimentos da carteira do cliente. Talvez alguém veja o código e consiga enxugar ele, mas como funcionou para minha necessidade e não tá demorando pra rodar, eu vou utilizar ele assim.

Agradeço muito o @Thanael pela ajuda.

 

 

CARTEIRAS_Leitor_XML_Anbima_Posicao_4_01.py

  • Curtir 2
Link to comment
Compartilhe em outros sites

  • 5 months later...

Crie uma conta ou entre para comentar 😀

Você precisa ser um membro para deixar um comentário.

Crie a sua conta

Participe da nossa comunidade, crie sua conta.
É bem rápido!

Criar minha conta agora

Entrar

Você já tem uma conta?
Faça o login agora.

Entrar agora


×
×
  • Create New...