Mostrando entradas con la etiqueta nodo. Mostrar todas las entradas
Mostrando entradas con la etiqueta nodo. Mostrar todas las entradas

jueves, 28 de noviembre de 2024

Python (XIV) obtener el valor de un nodo de un fichero xml que tiene namespaces

 Queremos extraer el contenido del nodo <ValorBinario> de este fichero xml que namespaces: 

Nos fijamos que el namespace marcado en naranja no tiene nombre, por tanto se aplicará a todas los nodos cuyas etiquetas no tenganprefijo del namespace como "contenido" o "ValorBinario"


<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<insidews:documento xmlns="http://administracionelectronica.gob.es/ENI/XSD/v1.0/documento-e/contenido" 
    xmlns:ns2="http://administracionelectronica.gob.es/ENI/XSD/v1.0/documento-e/metadatos" 
    xmlns:ns3="http://administracionelectronica.gob.es/ENI/XSD/v1.0/firma" 
    xmlns:ns4="http://www.w3.org/2000/09/xmldsig#" 
    xmlns:ns5="http://administracionelectronica.gob.es/ENI/XSD/v1.0/documento-e" 
    xmlns:ns6="https://ssweb.seap.minhap.es/Inside/XSD/v1.0/metadatosAdicionales" 
    xmlns:ns7="https://ssweb.seap.minhap.es/Inside/XSD/v1.0/documento-e" 
    xmlns:insidews="https://ssweb.seap.minhap.es/Inside/XSD/v1.0/WebService">
    <ns5:documento Id="ES_L01462384_2022_2_ACORDS_PLE000001">
        <contenido Id="CONTENIDO_DOCUMENTO">
            <ValorBinario>JVB..</ValorBinario>
            <NombreFormato>PDF</NombreFormato>
        </contenido>
        <ns2:metadatos Id="DOC_ES_L01462384_2022_2_ACORDS_PLE000001_METADATOS">
            <ns2:VersionNTI>http://administracionelectronica.gob.es/ENI/XSD/v1.0/documento-e</ns2:VersionNTI>
            <ns2:Identificador>ES_L01462384_2022_2_ACORDS_PLE000001</ns2:Identificador>
            <ns2:Organo>L01462384</ns2:Organo>
            <ns2:FechaCaptura>2024-11-05T00:00:00.000+01:00</ns2:FechaCaptura>
            <ns2:OrigenCiudadanoAdministracion>true</ns2:OrigenCiudadanoAdministracion>
            <ns2:EstadoElaboracion>
                <ns2:ValorEstadoElaboracion>EE99</ns2:ValorEstadoElaboracion>
            </ns2:EstadoElaboracion>
            <ns2:TipoDocumental>TD02</ns2:TipoDocumental>
        </ns2:metadatos>
        <ns3:firmas>
	   <ns3:firma Id="FIRMA_1">
                <ns3:TipoFirma>TF06</ns3:TipoFirma>
                <ns3:ContenidoFirma>
                    <ns3:FirmaConCertificado>
                        <ns3:ReferenciaFirma xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:string">#CONTENIDO_DOCUMENTO</ns3:ReferenciaFirma>
                    </ns3:FirmaConCertificado>
                </ns3:ContenidoFirma>
            </ns3:firma>
            <ns3:firma Id="FIRMA_2">
                <ns3:TipoFirma>TF06</ns3:TipoFirma>
                <ns3:ContenidoFirma>
                    <ns3:FirmaConCertificado>
                        <ns3:ReferenciaFirma xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:string">#CONTENIDO_DOCUMENTO</ns3:ReferenciaFirma>
                    </ns3:FirmaConCertificado>
                </ns3:ContenidoFirma>
            </ns3:firma>
        </ns3:firmas>
    </ns5:documento>
    <ns7:metadatosAdicionales>
        <ns6:MetadatoAdicional tipo="string" nombre="eEMGDE3.1.Nombre.NombreNatural">
            <ns6:valor xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:string">$5.NOM_DOC$</ns6:valor>
        </ns6:MetadatoAdicional>
    </ns7:metadatosAdicionales>
</insidews:documento>


para ello se ha creado este programa python

import base64
from lxml import etree

def extraer_pdf(xml_path, output_pdf_path):
    try:
        # Cargar el archivo XML
        with open(xml_path, "rb") as xml_file:
            xml_data = xml_file.read()
        
        # Parsear el XML
        tree = etree.fromstring(xml_data)
        
        # Definir los namespaces utilizados en el XML
        namespaces = {
            "insidews": "https://ssweb.seap.minhap.es/Inside/XSD/v1.0/WebService",
            "ns5": "http://administracionelectronica.gob.es/ENI/XSD/v1.0/documento-e",
            "contenido": "http://administracionelectronica.gob.es/ENI/XSD/v1.0/documento-e/contenido"
        }
        
        # Listar nodos para depuración
        print("Nodos disponibles:")
        for elem in tree.iter():
            print(f"{elem.tag}")

        # Buscar el contenido del tag <ValorBinario>
        valor_binario_node = tree.xpath(
            "//insidews:documento/ns5:documento/contenido:contenido/contenido:ValorBinario",
            namespaces=namespaces
        )
        
        if not valor_binario_node:
            raise ValueError("No se encontró el tag <ValorBinario> en el documento XML.")
        
        # Extraer el contenido en Base64
        valor_binario = valor_binario_node[0].text
        
        # Decodificar el contenido Base64
        pdf_data = base64.b64decode(valor_binario)
        
        # Guardar el contenido en el archivo PDF
        with open(output_pdf_path, "wb") as pdf_file:
            pdf_file.write(pdf_data)
        
        print(f"Archivo PDF extraído correctamente y guardado en: {output_pdf_path}")
    
    except Exception as e:
        print(f"Error al procesar el archivo XML: {e}")


# Ruta al archivo XML y al PDF de salida
xml_path = "/home/eduard/MyPython/02.llibreriesOLD/ximo-python-library/ES_L01462384_2022_2_ACORDS_PLE000001.xml"
output_pdf_path = "mifichero.pdf"

# Ejecutar la función
extraer_pdf(xml_path, output_pdf_path)


Y cuando nos lista los nodos aparece

{https://ssweb.seap.minhap.es/Inside/XSD/v1.0/WebService}documento
{http://administracionelectronica.gob.es/ENI/XSD/v1.0/documento-e}documento
{http://administracionelectronica.gob.es/ENI/XSD/v1.0/documento-e/contenido}contenido
{http://administracionelectronica.gob.es/ENI/XSD/v1.0/documento-e/contenido}ValorBinario
{http://administracionelectronica.gob.es/ENI/XSD/v1.0/documento-e/contenido}NombreFormato
{http://administracionelectronica.gob.es/ENI/XSD/v1.0/documento-e/metadatos}metadatos
{http://administracionelectronica.gob.es/ENI/XSD/v1.0/documento-e/metadatos}VersionNTI
{http://administracionelectronica.gob.es/ENI/XSD/v1.0/documento-e/metadatos}Identificador
{http://administracionelectronica.gob.es/ENI/XSD/v1.0/documento-e/metadatos}Organo
{http://administracionelectronica.gob.es/ENI/XSD/v1.0/documento-e/metadatos}FechaCaptura
{http://administracionelectronica.gob.es/ENI/XSD/v1.0/documento-e/metadatos}OrigenCiudadanoAdministracion
{http://administracionelectronica.gob.es/ENI/XSD/v1.0/documento-e/metadatos}EstadoElaboracion
{http://administracionelectronica.gob.es/ENI/XSD/v1.0/documento-e/metadatos}ValorEstadoElaboracion
{http://administracionelectronica.gob.es/ENI/XSD/v1.0/documento-e/metadatos}TipoDocumental
{http://administracionelectronica.gob.es/ENI/XSD/v1.0/firma}firmas
{http://administracionelectronica.gob.es/ENI/XSD/v1.0/firma}firma
{http://administracionelectronica.gob.es/ENI/XSD/v1.0/firma}TipoFirma
{http://administracionelectronica.gob.es/ENI/XSD/v1.0/firma}ContenidoFirma
{http://administracionelectronica.gob.es/ENI/XSD/v1.0/firma}FirmaConCertificado
{http://administracionelectronica.gob.es/ENI/XSD/v1.0/firma}ReferenciaFirma
{http://administracionelectronica.gob.es/ENI/XSD/v1.0/firma}firma
{http://administracionelectronica.gob.es/ENI/XSD/v1.0/firma}TipoFirma
{http://administracionelectronica.gob.es/ENI/XSD/v1.0/firma}ContenidoFirma
{http://administracionelectronica.gob.es/ENI/XSD/v1.0/firma}FirmaConCertificado
{http://administracionelectronica.gob.es/ENI/XSD/v1.0/firma}ReferenciaFirma
{https://ssweb.seap.minhap.es/Inside/XSD/v1.0/documento-e}metadatosAdicionales
{https://ssweb.seap.minhap.es/Inside/XSD/v1.0/metadatosAdicionales}MetadatoAdicional
{https://ssweb.seap.minhap.es/Inside/XSD/v1.0/metadatosAdicionales}valor

A raiz de todo esto vemos que en el fichero xml, la ruta a <ValorBinario> es:

<insidews:documento><ns5:documento><contenido><ValorBinario>

Por otra parte si reducimos el listado anterior:

{https://ssweb.seap.minhap.es/Inside/XSD/v1.0/WebService}documento
{http://administracionelectronica.gob.es/ENI/XSD/v1.0/documento-e}documento
{http://administracionelectronica.gob.es/ENI/XSD/v1.0/documento-e/contenido}contenido
{http://administracionelectronica.gob.es/ENI/XSD/v1.0/documento-e/contenido}ValorBinario

Vemos que contenido si tiene un namespace que es "contenido" y tambien ValorBinario tiene el namespace "contenido". Por tanto la ruta para llegar a valor binario es:


# Buscar el contenido del tag <ValorBinario>
valor_binario_node = tree.xpath(
   "//insidews:documento/ns5:documento/contenido:contenido/contenido:ValorBinario",
   namespaces=namespaces
)