Gern stehe ich zur fachlichen Unterstützung in XML-Technologien, C#.NET, VisualBasic.NET und Java zur Verfügung. Sprechen Sie mich einfach an: Mail oder ☎ 0151 . 750 360 61


XML und Datenbanken / XML-Datenbank: BaseX

XML-Datenbank: BaseX

XML-Datenbank: BaseX

➪ BaseX ist eine plattformunabhängige, leistungsfähige native OpenSource-XML Datenbank, die auch für unternehmenskritische Applikationen eine gute Alternative zu relationalen SQL-Datenbanken bietet. Erschienen in 2007, steht BaseX unter der BSD-Lizenz und aktuell in der Version 8.6.7 (September 2017) zur Verfügung.

Auf dieser Seite:

Der Hauptvorteil von XML-Datenbanken liegt in der syntaktisch einfachen und technisch effizienten Auswertung komplexer Datenstrukturen mit XPath/XQuery. Das ist wertvoll, weil Sie mithilfe der immer das vollständige Dokument verfügbar haben, egal von welchem Node Sie ausgehen. Das ist deutlich einfacher als bei relationalen SQL-Datenbanken, wo die Informationen aus verschiedenen Tabellen durch teilweise sehr aufwendige Abfragen zusammengeführt werden müssen.

Demgegenüber stehen technisch aufwendige Änderungen der Datenstruktur (insert, update, delete) bei nativen XML-Datenbanken, deren Performance bei sehr zahlreichen Einzeltransaktionen schlechter sein kann als im relationalen Modell. Auch gibt es kein Rollback oder Commit. Werden jedoch sehr zahlreiche Updates (im Rahmen einer einzigen Transaktion, es gibt nur einen Schreibprozess) auf einmal durchgeführt, dann sieht die Performance besser aus.

Damit ist BaseX hervorragend geeignet zur Aufnahme von Daten, die erfasst werden, ohne in jedem beliebigen Moment geändert werden zu sollen. Ein Beispiel ist die langfristige Datenhaltung von Rechnungen, Rentenbescheiden oder Messergebnissen, etwa medizinischer Laboruntersuchungen.

In Java geschrieben, werden diverse Betriebssysteme (Linux, OSX, Windows), APIs bzw. Konzepte (Java, RESTful HTTP, RESTXQ, WebDAV, XML:DB, XQJ) und Programmiersprachen (Actionscript, C, C#.NET, Haskell, Java, JavaScript: Node.js, Lisp, Perl, PHP, Python, Qt, Rebol, Buby, Scala und VisualBasic.NET) unterstützt.

Datenbanken anlegen, Werte einfügen, ändern, löschen

In BaseX ist das Anlegen und Füllen einer XML-Datenbank denkbar einfach. Erzeugen Sie die Datenbank wgTest, indem Sie ein XML-Dokument einbinden.


db:create("wgTest", "C:/wg/Ort_Elemente.xml")

Ein insert lässt sich ebenfalls leicht bewerkstelligen, indem Sie ein entsprechendes Kommando starten.


let $stadt := <Ort>
                <id>4</id>
                <name>Hauptstadt</name>
              </Ort>
return
  insert node $stadt into doc("wgTest")/Orte

Durch gezielte XPath-Adressierungen lassen sich in den soeben generierten Node Childnodes einfügen.


let $m := <Mensch>
            <id>20</id>
            <name>Hefeklos</name>
            <vorname>Herta</vorname>
            <Gehalt>321.45</Gehalt>
            <idOrt>4</idOrt>
          </Mensch>
return
  insert node $m into 
         doc("wgTest")/Orte/Ort[id="4"]

Nun gefällt es Ihnen, den Inhalt des vorher neu eingefügten Nodes zu verändern.


replace value of 
        node doc("wgTest")/Orte/Ort[id="4"]/name 
        with "Innenstadt"

Mit einer einfachen Abfrage können Sie den Erfolg Ihrer Bemühungen kontrollieren:


doc("wgTest")/Orte/Ort[id="4"]/name/text()

Auch können Nodes gezielt gelöscht werden.


delete node 
      doc("wgTest")/Orte/Ort/Mensch[Gehalt > 1000]

Nodes kopieren und umbenennen, ohne ein Update durchzuführen? Kein Problem mit


copy $c := doc("wgTest")/Orte/Ort[id="4"]
modify rename node $c as 'Nodecopy'
return $c

Die Node-Kopie sieht dann so aus:


<Nodecopy>
  <id>4</id>
  <name>Innenstadt</name>
  <Mensch>
    <id>20</id>
    <name>Hefeklos</name>
    <vorname>Herta</vorname>
    <Gehalt>321.45</Gehalt>
    <idOrt>4</idOrt>
  </Mensch>
</Nodecopy>

Ebenfalls ist es möglich, spezielle Module mit individuellen Signaturen zu schreiben, die dann anderweitig aufgerufen werden können.


module namespace wg="http://www.wilfried-grupe.de";
declare function 
       wg:quadriere($x as xs:integer) 
       as xs:integer 
       {$x * $x};
declare %public function 
       wg:suche_nach_Vorname 
          ($pattern  as xs:string) 
           as element(Mensch)* {
  for $m in doc("wgTest")//Mensch
          [matches(vorname, $pattern)]
  return $m
};
Datei: dba/modules/wgMod.xqm

Das soeben unter dba/modules/wgMod.xqm gespeicherte Modul können Sie anderweitig wieder einbinden und ausführen.


import module 
   namespace wg="http://www.wilfried-grupe.de"
   at "modules/wgMod.xqm";
for $y in 1 to 5 return wg:quadriere($y)

Das Ergebnis sollte nachvollziehbar sein:


1
4
9
16
25

Auch die erweiterte Funktion wg:suche_nach_Vorname lässt sich sinnvoll verwenden:


import module 
   namespace wg="http://www.wilfried-grupe.de"
   at "modules/wgMod.xqm";
<erg>
{
  for $mm in 
       wg:suche_nach_Vorname
          ('(R|S)[a-z]{1,}(a|e|i|o|u)$')
  return
  <m vn="{$mm/vorname/text()}" 
     nn="{$mm/name/text()}"/>
}
</erg>
Datei: dba/wgTest.xqm

Das Ergebnis sieht in diesem Fall so aus:


<erg>
  <m vn="Siggi"  nn="Sorglos"/>
  <m vn="Rudi"   nn="Rhodos"/>
  <m vn="Simone" nn="Sinnlos"/>
  <m vn="Rita"   nn="Ruhelos"/>
  <m vn="Susi"   nn="Schlaflos"/>
</erg>

Falls im Ergebnisdokument der Einsatz spezieller Namespaces benötigt wird, so ist das auch kein Problem.


import module 
   namespace wg="http://www.wilfried-grupe.de"
   at "modules/wgMod.xqm";
declare namespace j="http://www.w3.org/2013/XSL/json";
<j:array>
{
  for $mm in 
       wg:suche_nach_Vorname
          ('(R|S)[a-z]{1,}(a|e|i|o|u)$')
  return
  <j:map>
    <j:string key="vorname">
       {$mm/vorname/text()}
    </j:string>
    <j:string key="nachname">
       {$mm/name/text()}
    </j:string>
  </j:map>
}
</j:array>

Das Ergebnis bietet damit schon einmal grundsolide Voraussetzungen für die Weiter-Konvertierung nach mit :


<j:array xmlns:j="http://www.w3.org/2013/XSL/json">
  <j:map>
    <j:string key="vorname">Siggi</j:string>
    <j:string key="nachname">Sorglos</j:string>
  </j:map>
  <j:map>
    <j:string key="vorname">Rudi</j:string>
    <j:string key="nachname">Rhodos</j:string>
  </j:map>
  <j:map>
    <j:string key="vorname">Simone</j:string>
    <j:string key="nachname">Sinnlos</j:string>
  </j:map>
  <j:map>
    <j:string key="vorname">Rita</j:string>
    <j:string key="nachname">Ruhelos</j:string>
  </j:map>
  <j:map>
    <j:string key="vorname">Susi</j:string>
    <j:string key="nachname">Schlaflos</j:string>
  </j:map>
</j:array>

C#.NET-Client für BaseX

Für diverse Programmiersprachen stehen Client-Implementierungen bereit, beispielswweise in C#.NET:


BaseXClient.Session session;
session = new BaseXClient.Session("localhost", 1984, "admin", "admin");
string sXQuery = "for $x in (20 to 200) return $x";
BaseXClient.Query query = session.Query(sXQuery);
while (query.More())
{
    string sQuery = query.Next();
    Console.WriteLine(sQuery);
}
query.Close();
session.Close();   

Python-Client für BaseX

... oder in Python:


from BaseX_Client import Session
session = Session('localhost', 1984, 'admin', 'admin')
sum =0
try:
    input = "for $i in ((20 to 200)[. mod 19 = 0]) return $i"
    query = session.query(input)
    for  y, item in query.iter():
        sum += int(item)
        print("{0:>10}{1:>10}".format(item, sum))
    query.close()
    print ("Die Summe aller Zahlen ist {0}.".format(sum))
finally:
    if session:
        session.close()

wg / 30. März 2019



Fragen? Anmerkungen? Tipps?

Bitte nehmen Sie Kontakt zu mir auf.






Vielen Dank für Ihr Interesse an meiner Arbeit.


V.i.S.d.P.: Wilfried Grupe * Klus 6 * 37643 Negenborn

☎ 0151. 750 360 61 * eMail: info10@wilfried-grupe.de

www.wilfried-grupe.de/BaseX.html