Interrogation d’un fichier hprimXML avec python via xpath et lxml

Author

gpr

Published

August 16, 2024

import polars as pl
import lxml.etree as ET
import io
import os
# on va supprimer le xmlns avec ce script
def remove_namespaces(doc):
    # http://wiki.tei-c.org/index.php/Remove-Namespaces.xsl
    xslt='''<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="no"/>

    <xsl:template match="/|comment()|processing-instruction()">
        <xsl:copy>
          <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="*">
        <xsl:element name="{local-name()}">
          <xsl:apply-templates select="@*|node()"/>
        </xsl:element>
    </xsl:template>

    <xsl:template match="@*">
        <xsl:attribute name="{local-name()}">
          <xsl:value-of select="."/>
        </xsl:attribute>
    </xsl:template>
    </xsl:stylesheet>
    '''

    xslt_doc = ET.parse(io.StringIO(xslt))
    transform = ET.XSLT(xslt_doc)
    doc = transform(doc)
    return doc
# Définition des xpath où trouver les données, sans alias de namespace...
hprim_pmsi_mapping = dict(
    patient_ipp = "evenementPMSI/patient/identifiant/emetteur/valeur",
    patient_nom_usuel = "evenementPMSI/patient/personnePhysique/nomUsuel",
    patient_prenoms = "evenementPMSI/patient/personnePhysique/prenoms/*",
    patient_date_naissance = "evenementPMSI/patient/personnePhysique/dateNaissance/*",
    venue_iep = "evenementPMSI/venue/identifiant/emetteur/valeur",
    venue_date_debut = "evenementPMSI/venue/entree/dateHeureOptionnelle/*",
    venue_ufr = "evenementPMSI/venue/entree/uniteFonctionnelleResponsable/",
    rss_id = "evenementPMSI/rss/identifiantRSS/*",
    rss_rum_uf = "evenementPMSI/rss/rum/uniteMedicale/code",
    rss_rum_date_entree = "evenementPMSI/rss/rum/uniteMedicale/entree/*",
    rss_rum_dp = "evenementPMSI/rss/rum/diagnostics/diagnosticPrincipal/codeCim10",
    rss_rum_dr = "evenementPMSI/rss/rum/diagnostics/diagnosticRelie/codeCim10",
    rss_rum_ds = "evenementPMSI/rss/rum/diagnostics/diagnosticSignificatif/codeCim10/*",
    rss_rum_dd = "evenementPMSI/rss/rum/diagnostics/diagnosticDocumentaire/codeCim10/*",
    actes_ccam = "evenementPMSI/rss/rum/actes/acte/CCAM/codeActe",
    actes_date = "evenementPMSI/rss/rum/actes/acte/CCAM/dateRealisation"
)
# fonction pour extraire un élément qui est prudente (si l'élément n'existe pas, retourne None)
def get_element(tree, element):
     try:
         return  ' '.join(x.text 
                             for x in 
                             tree.findall(element)
                            )
     except:
        return None
# Récupérer un dictionnaire avec les informations pour un fichier XML
def parse_hprim_xml_pmsi(xml_file):
    u = ET.parse(xml_file)
    u =  remove_namespaces(u) # on supprime le namespace
    temp = dict()
    for key in hprim_pmsi_mapping.keys():
        temp[key] = get_element(u, hprim_pmsi_mapping.get(key))
    return temp
parse_hprim_xml_pmsi('../data/xml_tests/pmsi/00001.xml')
{'patient_ipp': '123456789',
 'patient_nom_usuel': 'SANDWICK',
 'patient_prenoms': 'JOHN',
 'patient_date_naissance': '1970-01-01',
 'venue_iep': '987654321',
 'venue_date_debut': '2024-01-01 08:00:00',
 'venue_ufr': '4321',
 'rss_id': '0 000',
 'rss_rum_uf': '4321 5000',
 'rss_rum_date_entree': '2024-01-01 08:00:00 2024-01-01 09:00:00',
 'rss_rum_dp': 'Z511 Z743',
 'rss_rum_dr': 'C10',
 'rss_rum_ds': '',
 'rss_rum_dd': '',
 'actes_ccam': 'EBLA003 EPLF002 NFKA006 YYYY033 QZRP004',
 'actes_date': '2024-01-01T08:10:00 2024-01-01T08:10:00 2024-01-01T08:10:00 2024-01-01T08:10:00 2024-01-01T09:10:00'}