Angenommen, Sie haben mehrere XML-Dateien zur Hand und möchten diese Daten abwägen. Für Menschen ist es schwierig, mehrere XML-Dateien zu vergleichen, daher werde ich sie in CSV-Dateien konvertieren, die eine Zeile pro XML-Datei enthalten. Wenn Sie die CSV-Datei mit Excel usw. öffnen, ist es einfacher, die Daten zu vergleichen und zu untersuchen. Ich habe die Konvertierung in CSV in Python implementiert, aber verzeihen Sie mir, dass sich der Code nicht sehr gut verhält.
--OS: Windows10 (Ich habe es nicht ausprobiert, aber es kann auf einem anderen Betriebssystem ausgeführt werden)
Laden Sie zunächst mehrere XML-Dokumente in BaseX. Ich habe den folgenden Python-Code unter Bezugnahme auf [Code hier] geschrieben und bearbeitet (https://github.com/BaseXdb/basex/tree/master/basex-api/src/main/python).
from pathlib import Path
import os
import pprint
from BaseXClient import BaseXClient
#Erstellen Sie eine Sitzung
session = BaseXClient.Session('localhost', 1984, 'admin', 'admin')
try:
    #XML-Datei, die in der Datenbank gespeichert werden soll
    xml_directory = Path("C:\\") / "xml_data"
    list_xml_path = sorted(xml_directory.glob("*.xml"), key=os.path.getmtime)
    print("Zu ladende XML-Datei:")
    pprint.pprint(list_xml_path)
    #DB offen
    session.execute("open testdb")
    print(session.info())
    #Lesen Sie die XML-Datei und fügen Sie sie der Datenbank hinzu
    for path in list_xml_path:
        with open(path, mode='r', encoding="utf-8") as fi:
            str_xml = fi.read()
        session.add(path.name, str_xml)
        print(session.info())
    #Zeigen Sie den Inhalt der Datenbank an
    print("\n" + session.execute("xquery /"))
    print("Normal abgeschlossen\n")
finally:
    #Sitzung schließen
    if session:
        session.close()
Um die Erklärung zum Code zu ergänzen,
--Laden Sie das XML-Dokument in die vorhandene Datenbank "testdb". Informationen zum Erstellen einer Datenbank finden Sie in diesem Artikel.
Als ich den Code ausführte, wurde das XML-Dokument mit der folgenden Anzeige geladen:
Zu ladende XML-Datei:
[WindowsPath('C:/xml_data/sample-1.xml'),
 WindowsPath('C:/xml_data/sample-2.xml'),
 WindowsPath('C:/xml_data/sample-3.xml'),
 WindowsPath('C:/xml_data/sample-4.xml'),
 WindowsPath('C:/xml_data/sample-5.xml'),
 WindowsPath('C:/xml_data/sample-7.xml'),
 WindowsPath('C:/xml_data/sample-6.xml'),
 WindowsPath('C:/xml_data/sample-8.xml')]
Database 'testdb' was opened in 1.48 ms.
Resource(s) added in 3.72 ms.
Resource(s) added in 1.93 ms.
Resource(s) added in 8.89 ms.
Resource(s) added in 1.91 ms.
Resource(s) added in 2.05 ms.
Resource(s) added in 2.05 ms.
Resource(s) added in 1.93 ms.
(Weggelassen)
Normal abgeschlossen
Anschließend wird BaseX abgefragt, um eine CSV-Datei auszugeben, die ein XML-Dokument zu einer Zeile macht. Ich habe den folgenden Python-Code geschrieben und es hat funktioniert.
import pprint
from BaseXClient import BaseXClient
#Eigene Ausnahmeklasse
class MyException(Exception):
    pass
#Lesen Sie den xpath des Stammelements aus der Datenbank
def read_xpath_root(session):
    set_xpath_root = set()
    query = f'''\
for $root in /*
return fn:path($root)
'''
    query_obj = session.query(query)
    query_obj.execute()
    #Fügen Sie einer eindeutigen Menge xpaths für alle Stammelemente hinzu
    for typecode, item in query_obj.iter():
        set_xpath_root.add(item)
    print("XPath des Wurzelelements:")
    pprint.pprint(set_xpath_root)
    query_obj.close()
    #Ich habe beschlossen, nur einen Typ von Wurzelelement zuzulassen.
    if len(set_xpath_root) == 1:
        pass
    else:
        msg = f"assert len(set_xpath_root)<{len(set_xpath_root)}> == 1"
        raise MyException(msg)
    return set_xpath_root.pop().replace("[1]", "[01]") + '/'
#Sammeln Sie alle Arten von xpath des Textelements aus der Datenbank
def read_xpath_text(session):
    set_xpath_text = set()
    query = f'''\
for $text in //text()
return fn:path($text)
'''
    query_obj = session.query(query)
    query_obj.execute()
    #Fügen Sie xpath aller Textelemente zu einem nicht doppelten Satz hinzu
    for typecode, item in query_obj.iter():
        set_xpath_text.add(item)
    query_obj.close()
    #Ich möchte sortieren, also vom Set zur Liste wechseln
    list_xpath_text = []
    for xpath_text in set_xpath_text:
        list_xpath_text.append(
            #Beim Sortieren[1]Aber[10]Für Probleme, die später sein werden. Vorerst
            xpath_text
                .replace("[1]", "[01]")
                .replace("[2]", "[02]")
                .replace("[3]", "[03]")
                .replace("[4]", "[04]")
                .replace("[5]", "[05]")
                .replace("[6]", "[06]")
                .replace("[7]", "[07]")
                .replace("[8]", "[08]")
                .replace("[9]", "[09]")
        )
    list_xpath_text.sort()
    print("XPath des Textelements (alle Typen):")
    pprint.pprint(list_xpath_text)
    return list_xpath_text
#Erstellen Sie eine Sitzung
session = BaseXClient.Session('localhost', 1984, 'admin', 'admin')
try:
    #DB offen
    session.execute("open testdb")
    print(session.info())
    #Lesen Sie den xpath des Stammelements
    xpath_root = read_xpath_root(session)
    #Sammeln Sie alle Arten von xpath des Textelements (verwenden Sie den Namen der CSV-Spalte).
    list_xpath_text = read_xpath_text(session)
    #Stellen Sie eine Abfrage zusammen und geben Sie sie aus, die eine Zeile csv zurückgibt
    csv_header = "input_path"
    query = f'''\
for $root in /*
let $base_uri := fn:base-uri($root)
order by $base_uri
return <ROW>"{{fn:substring($base_uri, fn:string-length(db:name($root)) + 3)}}"\
'''
    #CSV-Spaltenschleife
    for xpath_text in list_xpath_text:
        # xpath_Formatieren Sie entsprechend vom Text zum CSV-Header.+=
        csv_header += ',' \
                      + xpath_text\
                          .replace(xpath_root, "")\
                          .replace("/text()[01]", "")\
                          .replace("Q{}", "")
        # xpath_Format aus Text für XQuery,+=
        query += ',"{' + xpath_text.replace(xpath_root, "$root/") + '}"'
    query += "</ROW>"
    #DB-Anfrage
    query_obj = session.query(query)
    query_obj.execute()
    #Name der Ausgabedatei
    basename = xpath_root\
                       .replace("Q{}", "")\
                       .replace("[01]", "")\
                       .replace('/', "")
    #Ausgabe der Abfrageanweisung
    with open(basename + "_xquery.txt", 'w') as fo:
        fo.write(query)
        fo.write('\n')
    #CSV-Ausgabe
    with open(basename + ".csv", 'w') as fo:
        #Header-Ausgabe
        fo.write(csv_header)
        fo.write('\n')
        #Leitungsausgang
        for typecode, item in query_obj.iter():
            fo.write(item.replace("<ROW>", "").replace("</ROW>", '\n'))
    query_obj.close()
    print("Normal abgeschlossen\n")
finally:
    #Sitzung schließen
    if session:
        session.close()
Um die Erklärung zum Code zu ergänzen,
--Dieser Code erfordert, dass alle XML-Dokumente in der Datenbank denselben Stammelementnamen haben.
Als ich den Code ausführte, wurde Folgendes angezeigt und die CSV-Datei "manyosyu.csv" ausgegeben.
Database 'testdb' was opened in 1.12 ms.
XPath des Wurzelelements:
{'/Q{}manyosyu[1]'}
XPath des Textelements (alle Typen):
['/Q{}manyosyu[01]/Q{}volume[01]/Q{}poem[01]/Q{}image[01]/text()[01]',
 '/Q{}manyosyu[01]/Q{}volume[01]/Q{}poem[01]/Q{}mean[01]/text()[01]',
 '/Q{}manyosyu[01]/Q{}volume[01]/Q{}poem[01]/Q{}mkana[01]/text()[01]',
 '/Q{}manyosyu[01]/Q{}volume[01]/Q{}poem[01]/Q{}pno[01]/text()[01]',
 '/Q{}manyosyu[01]/Q{}volume[01]/Q{}poem[01]/Q{}poet[01]/text()[01]',
 '/Q{}manyosyu[01]/Q{}volume[01]/Q{}poem[01]/Q{}yomi[01]/text()[01]',
 '/Q{}manyosyu[01]/Q{}volume[01]/Q{}poem[02]/Q{}image[01]/text()[01]',
 '/Q{}manyosyu[01]/Q{}volume[01]/Q{}poem[02]/Q{}mean[01]/text()[01]',
 '/Q{}manyosyu[01]/Q{}volume[01]/Q{}poem[02]/Q{}mkana[01]/text()[01]',
 '/Q{}manyosyu[01]/Q{}volume[01]/Q{}poem[02]/Q{}pno[01]/text()[01]',
 '/Q{}manyosyu[01]/Q{}volume[01]/Q{}poem[02]/Q{}poet[01]/text()[01]',
 '/Q{}manyosyu[01]/Q{}volume[01]/Q{}poem[02]/Q{}yomi[01]/text()[01]',
 '/Q{}manyosyu[01]/Q{}volume[01]/Q{}poem[03]/Q{}image[01]/text()[01]',
 '/Q{}manyosyu[01]/Q{}volume[01]/Q{}poem[03]/Q{}mean[01]/text()[01]',
 '/Q{}manyosyu[01]/Q{}volume[01]/Q{}poem[03]/Q{}mkana[01]/text()[01]',
 '/Q{}manyosyu[01]/Q{}volume[01]/Q{}poem[03]/Q{}pno[01]/text()[01]',
 '/Q{}manyosyu[01]/Q{}volume[01]/Q{}poem[03]/Q{}poet[01]/text()[01]',
 '/Q{}manyosyu[01]/Q{}volume[01]/Q{}poem[03]/Q{}yomi[01]/text()[01]',
 '/Q{}manyosyu[01]/Q{}volume[01]/Q{}poem[04]/Q{}image[01]/text()[01]',
 '/Q{}manyosyu[01]/Q{}volume[01]/Q{}poem[04]/Q{}mean[01]/text()[01]',
 '/Q{}manyosyu[01]/Q{}volume[01]/Q{}poem[04]/Q{}mean[01]/text()[02]',
 '/Q{}manyosyu[01]/Q{}volume[01]/Q{}poem[04]/Q{}mkana[01]/text()[01]',
 '/Q{}manyosyu[01]/Q{}volume[01]/Q{}poem[04]/Q{}pno[01]/text()[01]',
 '/Q{}manyosyu[01]/Q{}volume[01]/Q{}poem[04]/Q{}poet[01]/text()[01]',
 '/Q{}manyosyu[01]/Q{}volume[01]/Q{}poem[04]/Q{}yomi[01]/text()[01]',
 '/Q{}manyosyu[01]/Q{}volume[01]/Q{}poem[05]/Q{}image[01]/text()[01]',
 '/Q{}manyosyu[01]/Q{}volume[01]/Q{}poem[05]/Q{}mean[01]/text()[01]',
 '/Q{}manyosyu[01]/Q{}volume[01]/Q{}poem[05]/Q{}mkana[01]/text()[01]',
 '/Q{}manyosyu[01]/Q{}volume[01]/Q{}poem[05]/Q{}pno[01]/text()[01]',
 '/Q{}manyosyu[01]/Q{}volume[01]/Q{}poem[05]/Q{}poet[01]/text()[01]',
 '/Q{}manyosyu[01]/Q{}volume[01]/Q{}poem[05]/Q{}yomi[01]/text()[01]',
 '/Q{}manyosyu[01]/Q{}volume[01]/Q{}poem[06]/Q{}image[01]/text()[01]',
 '/Q{}manyosyu[01]/Q{}volume[01]/Q{}poem[06]/Q{}mean[01]/text()[01]',
 '/Q{}manyosyu[01]/Q{}volume[01]/Q{}poem[06]/Q{}mkana[01]/text()[01]',
 '/Q{}manyosyu[01]/Q{}volume[01]/Q{}poem[06]/Q{}pno[01]/text()[01]',
 '/Q{}manyosyu[01]/Q{}volume[01]/Q{}poem[06]/Q{}poet[01]/text()[01]',
 '/Q{}manyosyu[01]/Q{}volume[01]/Q{}poem[06]/Q{}yomi[01]/text()[01]']
Normal abgeschlossen
Die folgende Debugging-Datei für Abfrageanweisungen wird ebenfalls ausgegeben.
manyosyu_xquery.txt
for $root in /*
let $base_uri := fn:base-uri($root)
order by $base_uri
return <ROW>"{fn:substring($base_uri, fn:string-length(db:name($root)) + 3)}","{$root/Q{}volume[01]/Q{}poem[01]/Q{}image[01]/text()[01]}","{$root/Q{}volume[01]/Q{}poem[01]/Q{}mean[01]/text()[01]}","{$root/Q{}volume[01]/Q{}poem[01]/Q{}mkana[01]/text()[01]}","{$root/Q{}volume[01]/Q{}poem[01]/Q{}pno[01]/text()[01]}","{$root/Q{}volume[01]/Q{}poem[01]/Q{}poet[01]/text()[01]}","{$root/Q{}volume[01]/Q{}poem[01]/Q{}yomi[01]/text()[01]}","{$root/Q{}volume[01]/Q{}poem[02]/Q{}image[01]/text()[01]}","{$root/Q{}volume[01]/Q{}poem[02]/Q{}mean[01]/text()[01]}","{$root/Q{}volume[01]/Q{}poem[02]/Q{}mkana[01]/text()[01]}","{$root/Q{}volume[01]/Q{}poem[02]/Q{}pno[01]/text()[01]}","{$root/Q{}volume[01]/Q{}poem[02]/Q{}poet[01]/text()[01]}","{$root/Q{}volume[01]/Q{}poem[02]/Q{}yomi[01]/text()[01]}","{$root/Q{}volume[01]/Q{}poem[03]/Q{}image[01]/text()[01]}","{$root/Q{}volume[01]/Q{}poem[03]/Q{}mean[01]/text()[01]}","{$root/Q{}volume[01]/Q{}poem[03]/Q{}mkana[01]/text()[01]}","{$root/Q{}volume[01]/Q{}poem[03]/Q{}pno[01]/text()[01]}","{$root/Q{}volume[01]/Q{}poem[03]/Q{}poet[01]/text()[01]}","{$root/Q{}volume[01]/Q{}poem[03]/Q{}yomi[01]/text()[01]}","{$root/Q{}volume[01]/Q{}poem[04]/Q{}image[01]/text()[01]}","{$root/Q{}volume[01]/Q{}poem[04]/Q{}mean[01]/text()[01]}","{$root/Q{}volume[01]/Q{}poem[04]/Q{}mean[01]/text()[02]}","{$root/Q{}volume[01]/Q{}poem[04]/Q{}mkana[01]/text()[01]}","{$root/Q{}volume[01]/Q{}poem[04]/Q{}pno[01]/text()[01]}","{$root/Q{}volume[01]/Q{}poem[04]/Q{}poet[01]/text()[01]}","{$root/Q{}volume[01]/Q{}poem[04]/Q{}yomi[01]/text()[01]}","{$root/Q{}volume[01]/Q{}poem[05]/Q{}image[01]/text()[01]}","{$root/Q{}volume[01]/Q{}poem[05]/Q{}mean[01]/text()[01]}","{$root/Q{}volume[01]/Q{}poem[05]/Q{}mkana[01]/text()[01]}","{$root/Q{}volume[01]/Q{}poem[05]/Q{}pno[01]/text()[01]}","{$root/Q{}volume[01]/Q{}poem[05]/Q{}poet[01]/text()[01]}","{$root/Q{}volume[01]/Q{}poem[05]/Q{}yomi[01]/text()[01]}","{$root/Q{}volume[01]/Q{}poem[06]/Q{}image[01]/text()[01]}","{$root/Q{}volume[01]/Q{}poem[06]/Q{}mean[01]/text()[01]}","{$root/Q{}volume[01]/Q{}poem[06]/Q{}mkana[01]/text()[01]}","{$root/Q{}volume[01]/Q{}poem[06]/Q{}pno[01]/text()[01]}","{$root/Q{}volume[01]/Q{}poem[06]/Q{}poet[01]/text()[01]}","{$root/Q{}volume[01]/Q{}poem[06]/Q{}yomi[01]/text()[01]}"</ROW>
Öffnen wir die generierte "manyosyu.csv" in Excel.

Für jede in die Datenbank geladene XML-Datei wurde eine CSV-Zeile generiert.
Recommended Posts