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