XML-File durchsuchen ...

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
drnicolas
User
Beiträge: 105
Registriert: Sonntag 24. Juli 2016, 10:32

Ich habe begonnen mit zbarimg zu experiementieren.

Das liefert auf Wunsch xml-Daten zurück

<barcodes xmlns='http://zbar.sourceforge.net/2008/barcode'>
<source href='20211023_ecoDMS_070617.tif'>
<index num='6'>
<symbol type='CODE-128' quality='3' orientation='UP'><data><![CDATA[**123456789012**]]></data></symbol>
</index>
</source>
</barcodes>

ich möchte nun nach Elementen "index" suchen, bei denen CDATA **12345678912** ist.
Ich brauche vor allem 'num'

U.U. wiederholen sich diese Elemente mehrfach.

Ich habe zwar etwas mit etree experimentiert, bin aber nicht wirklich weitergekommen.

Kann mir jemadn helfen?
Sirius3
User
Beiträge: 18279
Registriert: Sonntag 21. Oktober 2012, 17:20

Was hast Du schon versucht? Wo kommst Du nicht weiter?
Das <![CDATA[ ist im XML spezifiziert und ist nicht Teil der Daten. Du mußt darauf achten dass die Tags Namespaces haben "{http://zbar.sourceforge.net/2008/barcode}index".
drnicolas
User
Beiträge: 105
Registriert: Sonntag 24. Juli 2016, 10:32

Ich komme einfach nicht weiter.
ich habe auf einem gefundenen Beispiel basieredn versucht das hin zu bekommen:

rom xml.dom import minidom

def main():


xmldoc = minidom.parse('/var/spool/scanning/result.xml')

stringlist = xmldoc.getElementsByTagName('barcodes')
print(len(stringlist))
print(stringlist[0].attributes['symbol'].value)
for x in stringlist:
print(x.attributes['name'].value)


Das produziert aber gar nichts.
Ich hätte erwartet, in stringlist meine Elemente zu entdecken.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Mit minidom zu arbeiten ist nicht zu empfehlen, und grenzt an Masochismus - das ist nur noch fuer Abwaertskompatibilitaet da. Dafuer benutzt man ElementTree (steht sogar im ersten Absatz der minidom-Doku als Hinweis), bzw etree, oder gleich lxml. Damit sollte sich auch gleich eine XPATH-Abfrage auf den data-Abkoemmling eines barcodes-Elementes machen lassen: "//barcodes//data", und dann in den Elementen das text-Attribut. Das ist jetzt allerdings nur aus dem Kopf.
Sirius3
User
Beiträge: 18279
Registriert: Sonntag 21. Oktober 2012, 17:20

`stringlist` ist keine Liste von Strings, sondern eine Liste mit XML-Elementen. Falsche Variablennamen führen zu nicht verstehbarem Code, deshalb muß man sehr sorgfältig sein, wie man Variablen benennt. `x´ für irgendetwas anderes als eine Kommazahl zu benutzen ist sehr verwirrend, das ist so, wie wenn Du ein Kuchenrezept schreiben würdest und statt Mehl immer Salz schreiben würdest, und statt Eiern Katze.

`symbol` ist dann auch ein XML-Tag, warum denkst Du, dass Du da in attributes fündig wirst? `name` kommt in Deinen Beispiel-XML gar nicht vor, also entweder hast Du hier ein falsche Beispiel gepostet, oder der Code ist auch in diesem Punkt falsch.

Code: Alles auswählen

import xml.etree.ElementTree as et

XMLDATA = """<barcodes xmlns='http://zbar.sourceforge.net/2008/barcode'>
<source href='20211023_ecoDMS_070617.tif'>
<index num='6'>
<symbol type='CODE-128' quality='3' orientation='UP'><data><![CDATA[**123456789012**]]></data></symbol>
</index>
</source>
</barcodes>"""

def main():
    barcodes = et.fromstring(XMLDATA)
    for source in barcodes.findall('.//{http://zbar.sourceforge.net/2008/barcode}source'):
        print(source.attrib['href'])
        for index in source.findall('{http://zbar.sourceforge.net/2008/barcode}index'):
            print(index.attrib['num'])
            print(index.findtext('{http://zbar.sourceforge.net/2008/barcode}symbol/{http://zbar.sourceforge.net/2008/barcode}data'))

if __name__ == "__main__":
    main()
Benutzeravatar
__blackjack__
User
Beiträge: 14078
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Mit dem externen `lxml.etree` kann man sich das mit den Namespaces ein bisschen einfacher machen:

Code: Alles auswählen

#!/usr/bin/env python3
from lxml import etree

XMLDATA = """\
<barcodes xmlns='http://zbar.sourceforge.net/2008/barcode'>
  <source href='20211023_ecoDMS_070617.tif'>
    <index num='6'>
      <symbol type='CODE-128' quality='3' orientation='UP'>
        <data><![CDATA[**123456789012**]]></data>
      </symbol>
    </index>
  </source>
</barcodes>
"""


def main():
    barcodes = etree.fromstring(XMLDATA)
    namespaces = barcodes.nsmap
    for source in barcodes.findall(".//source", namespaces=namespaces):
        print(source.get("href"))
        for index in source.findall("index", namespaces=namespaces):
            print(index.get("num"))
            print(index.findtext("symbol/data", namespaces=namespaces))


if __name__ == "__main__":
    main()
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Sirius3
User
Beiträge: 18279
Registriert: Sonntag 21. Oktober 2012, 17:20

Das ist gefährlich, wenn man doch ein XML bekommt, bei dem der Namespace einen Namen hat. Deshalb den Namespace explizit angeben!

Code: Alles auswählen

from lxml import etree

NAMESPACES = {None: 'http://zbar.sourceforge.net/2008/barcode'}

XMLDATA = """\
<ns:barcodes xmlns:ns='http://zbar.sourceforge.net/2008/barcode'>
  <ns:source href='20211023_ecoDMS_070617.tif'>
    <ns:index num='6'>
      <ns:symbol type='CODE-128' quality='3' orientation='UP'>
        <ns:data><![CDATA[**123456789012**]]></ns:data>
      </ns:symbol>
    </ns:index>
  </ns:source>
</ns:barcodes>
"""


def main():
    barcodes = etree.fromstring(XMLDATA)
    for source in barcodes.findall(".//source", namespaces=NAMESPACES):
        print(source.get("href"))
        for index in source.findall("index", namespaces=NAMESPACES):
            print(index.get("num"))
            print(index.findtext("symbol/data", namespaces=NAMESPACES))


if __name__ == "__main__":
    main()
Antworten