Sida 1 av 1

PYTHON: Läsa ur XML data och skriva xlsx

Postat: 6 februari 2024, 13:29:03
av Repaterion
God middag!

Denna gången sitter jag med ett urläsningsproblem på jobbet, där jag sitter nu är att elemtree fullständigt vägrar att läsa ur negativa värde, detta är konsekvent.
Python: 3,11 64b
Win 10.
VScode.

Första funktionen är att skapa "root" för aml-filen.

Kod: Markera allt

def xml_parser():
    tree = ET.parse(r'sökväg\till\test_data_full.xml')
    root = tree.getroot()
    return root
I urläsnings def så gör detta.

Kod: Markera allt

def aql_validation() -> None:
    row = 1
    root = xml_parser()

    cog_find = root.findall('.//Test[@TestID="4;1"]')
    mmi_find = root.findall('.//Test[@TestID="5;1"]')
    dlx_mid_find = root.findall('.//Test[@TestID="3;7"]')
    
    for aql_iter, cog, mmi_iter, dlx_mid_iter in zip_longest(aql_test, cog_find, mmi_find, dlx_mid_find):
        
        av = aql_iter.get('AQL').lower()

        if cog is not None:
            cog_collect = cog.attrib['Value'].strip("'[]").replace(',','.')
        else:
            cog_collect = None
        
        if mmi_iter is not None:
            mmi_collect = mmi_iter.attrib['Value'].strip("'[]").replace(',','.')
        else:
            mmi_collect = None
            
        if dlx_mid_iter is not None:
            dlx_mid_collect = dlx_mid_iter.attrib['Value'].strip("'[]")#.replace(',','.')
        else:
            dlx_mid_collect = None


        if  av == "true":
            if cog_collect is not None:
                worksheet.write_number(f'B{row}', float(cog_collect), None)
            if mmi_collect is not None:
                worksheet.write(f'C{row}', float(mmi_collect), None)
            
            if dlx_mid_collect is not None:
                worksheet.write(f'E{row}', float(dlx_mid_collect), None)
        if av == "false":
            if cog_collect is not None:
                try:
                    worksheet.write(f'B{row}', float(cog_collect), None)
                except ValueError as ver:
                    pass
            if mmi_collect is not None:
                try:
                    worksheet.write(f'C{row}', float(mmi_collect), None)
                except ValueError as ver:
                    pass
            #print("AQL False", (cog_parse()))
            falsk +=1
            row += 1
            # Non AQL kör utan detta.cog_parse()
    workbook.close() -> DENNA ÖPPNAS UTANFÖR FUNKTIONEN. Data skrivs till den.


Ett utdrag ur XML-data.

Kod: Markera allt


AQL TRUE
<?xml version="1.0" encoding="utf-8"?>
<Tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <TestProgram TestTime="36" AQL="true""> 
    <Test Type="DLX" TestID="3;7" Result="true" Value="-48" Min="-999" Max="-43" TestCnt="1" />
    <Test Type="COG" TestID="4;1" Result="true" Value="10,6" Min="6" Max="999" TestCnt="1" />
    <Test Type="MMI" TestID="5;1" Result="true" Value="56,55" Min="50" Max="999" TestCnt="1" />
  </TestProgram>

AQL FALSE
  <TestProgram TestTime="5" AQL="false" ">
    <Test Type="COG" TestID="4;1" Result="true" Value="10,4" Min="6" Max="999" TestCnt="1" />
    <Test Type="MMI" TestID="5;1" Result="true" Value="67,00" Min="50" Max="999" TestCnt="1" />
  </TestProgram>
</Tests>
När jag kör mitt skript så läses COG ut i båda AQL men inte de negativa värdena i AQl TRUE.
Jag har dubbelkollat i excelfilen att det "bör" vara på samma plats. Det är konsekvent att den inte läser ur detta.
COG och MMI återkommer hela tiden när jag jämför mot XML-filen men aldrig DLX värdet till trots att jag läser på samma sätt varje gång.

Var är det jag missar något fundamentalt?
Jag har en version 1.0 av detta program vilket använder regex i stället och den fungerar utmärkt tills dess någon ansåg att vi skall göra som "datastrukturen" i databasen.
Tänkte att då är nog elemtree ett bättre val och borde vara mer stabilt, men nu har jag fastnat totalt här, i excelfilen har jag 1500 rader med data men inga negativa värden, enbart COG och MMI, det är sex värden som fattas med jämna mellanrumm.

Kör en print på vilken del den går in i på aql true falls, med resultatet
Antal: AQL 18
Antal: !AQL 1584
Vilket stämmer med verkligheten (det är en liten fil) då AQL-true är ungefär var 100 beroende p åhur testen har gått.

Re: PYTHON: Läsa ur XML data och skriva xlsx

Postat: 6 februari 2024, 15:08:08
av Repaterion
Mer tester gjorda.

Testat med annat TestID fungerar, ändrat detta ID från 4 till -4: Fungerar.
Döpt om DLX till DLXH uti fall den blir förvirrad av att det finns flera DLX: Ingen skillnad.
Ändrat TestID för DLX från 3;9 till 345 eller 3;56: Ingen skillnad.
Flyttat plats på denna: Ingen skillnad.
Ändrat ordningen i xml-filen: Ingen skillnad.


Allt utom just dessa 6 värden kommer ut, allt annat är None. :evil:

Kört print på "elementet": [<Element 'Test' at 0x00000195568971F0>, <Element 'Test' at 0x00000195568B4360>] Så nog finns det något där antar jag, det finns bara två ställen i denna filen jag testkör mot.

Re: PYTHON: Läsa ur XML data och skriva xlsx

Postat: 6 februari 2024, 15:30:06
av mounte
Har du testat att börja validera din xml... ser ut som att det är lite för många dubbelfnuttar, i alla fall i exempel xml du postade:

Kod: Markera allt

här efter true två dubbelfnuttar
<TestProgram TestTime="36" AQL="true"">   <----------

och här efter false, " "
<TestProgram TestTime="5" AQL="false" ">

Re: PYTHON: Läsa ur XML data och skriva xlsx

Postat: 6 februari 2024, 17:23:55
av pi314
Bra spaning mounte!

Jag brukar köra W3Cs validator.

https://validator.w3.org/nu/

Den hade 26 anmärkningar på XML-koden ovan, varav 21 fel (error).

/Pi

Re: PYTHON: Läsa ur XML data och skriva xlsx

Postat: 7 februari 2024, 08:46:18
av Repaterion
@mounte
Den extra " har nog tillkommit i all hast för originalfilen har inte denna, jag bara klippte ut minsta möjliga data för att ha något att visa. :)
Det riktiga ser ut så här: 0" AQL="false" B, 0" och B är från föregående och efterkommande data bara.


@ Pi314
Det var som sagt bara ett stycke ur filen så att den genererar fel är inte konstigt alls.

Men om det vore fel i filen så hade jag förstått att det blir fel vid utläsningen via tex Python, men det är ju konsekvent just dessa data.
Oavsett dess namn, ID, värde etc. Alla annan data kan läsas.
Dess upplägg är identiskt med alla annan data i xml-filen.

Re: PYTHON: Läsa ur XML data och skriva xlsx

Postat: 7 februari 2024, 08:52:35
av Repaterion
Öppnade även filen i Notepadd++ för att se om det fanns mer skit i mellan någonstans med det är tomt, enda som finns är nyradstecken \n och vagnretur \r eller som det står i windås CR LF och dessa är i slutet av varje rad som sig bör.

Re: PYTHON: Läsa ur XML data och skriva xlsx

Postat: 7 februari 2024, 10:33:43
av guckrum
Ofta är det bra att skapa ett minimalt exempel på felet och jobba med det. Eller bygga från noll och uppåt tills felet uppstår. Men det har du kanske redan provat.

Re: PYTHON: Läsa ur XML data och skriva xlsx

Postat: 7 februari 2024, 10:52:57
av Repaterion
Japp, jag och en kollega har gjort en minivariant av detta och det ger samma resultat.
Det är den vi prövat med olika typen av värden så som neg, pos, andra testid etc etc.

Re: PYTHON: Läsa ur XML data och skriva xlsx

Postat: 7 februari 2024, 11:17:45
av Repaterion
Nu har det hänt något som gör mig än mer förbryllad.
I mini-versionen så ser det ut så här.

dlx_low skrivs inte ut medan dlx_high skrivs ut.. :roll:
Denna är bara för att se om det fanns något i variabeln. -> print(dlx_low_collect, " I IF") vilket det gör, oavsett om det skrivs ut eller ej.

Kod: Markera allt


def print_xml():
    for cog, mmi_iter, dlx_low_iter, dlx_high_iter in zip_longest(cog_find, mmi_find, dlx_lw_find, dlx_hg_find):
        if cog is not None:
            cog_collect = cog.attrib['Value'].strip("'[]").replace(',','.')
        else:
            cog_collect = None
        
        if mmi_iter is not None:
            mmi_collect = mmi_iter.attrib['Value'].strip("'[]").replace(',','.')
        else:
            mmi_collect = None
        
        if dlx_low_iter is not None:
            dlx_low_collect = dlx_low_iter.attrib['Value'].strip("'[]")#.replace(',','.')
            print(dlx_low_collect, " I IF")
        else:
            dlx_low_collect = None

        if dlx_high_iter is not None:
            dlx_high_collect = dlx_high_iter.attrib['Value'].strip("'[]")#.replace(',','.')
        # else:
        #     dlx_high_collect = None


efter detta finns en print()

När dlx_low/high har bort-kommenterade else så skrivs datan ut...
Då är ju inte dlx_low None.... :humm:

print() i dlx_low skriver ut båda värdena från filen.

Rätta mig nu, men NULL finns inte i Python utan detta är ersatt utav None.
NULL är ett "noll" värde kan man säga för att tala om att "fältet" är tomt.
Men adressen är ju inte NULL/None för det finns bevisligen data på minnesadressen, jag kan inte se någon logisk förklaring på varför just dessa inte läses korrekt.
Hade den enbart vägrat skriva ut när de var 3;X eller DLX i namnet så hade det teortiskt sett kunnat vara en krock mot classen eller vad nu modulen är, men då skulle ju inte tex GNU eller testID 25;5 skapa samma problem.