⚒️
BASEX XML DATABASE
Favorites
Notebook Data Access
Tags
Last edited time @December 11, 2024 12:59 PM
Archive
Created time @December 5, 2024 4:28 PM
INTRODUCTION
In order to search for a document in a baseX database, the following code is used
doc('pathIntroduintNomBD') . Example
doc('BD/economia/empresa.xml')
Keep in mind that the Bd is the name of the database that is stored in baseX, and
the subsequent path is where an item can be found in that database.
To look up all the documents in a created database path we use the code
for $i in collection('path') return document-uri($i) . Example
for $i in collection('/practica')
return document-uri($i)
If the path isn’t indicated. BabseX will show all the documents in the opened
Database.
BASEX XML DATABASE 1
UPDATE STATEMENTS IN BASEX
Insert - One or various nodes into one or more various
nodes
If the insertion ( one or more nodes ) is being inserted into various nodes. The
FLOWR paradigm should be used
for $n in onInserir return
insert (node | nodes) (nodeAInserir | seqüènciaNodes)
((as (first | last))? into) | after | before $n
If the insertion is only for one node then the following should be used instead
insert (node | nodes) (nodeAInserir | seqüènciaNodes)
((as (first | last))? into) | after | before onInserir
In case of a sequence of nodes then the nodes should be placed in parenthesis
separated by a coma. into: placed after the indicated location
Example: Inserting a single department after a node
insert node (<dept codi="d50">
<nom>RRHH</nom>
<localitat>Igualda</localitat></dept>)
after doc('/Practica/economia/empresa.xml') //dept[@codi="d40"]
Insert - One or more attributes into one or more nodes
If the insertion ( one or more attributes) is being inserted into various nodes. The
FLOWR paradigm should be used
BASEX XML DATABASE 2
for $n in onInserir return
insert (node | nodes) (attribute nomAtribut {'valor'},...)
((as (first | last))? into) | after | before $n
If inserting into only one node then there is no use to use for
insert (node | nodes) (attribute nomAtribut {'valor'},...)
((as (first | last))? into) | after | before onInserir
Sequences of nodes should be in parenthesis separated by a coma.
Example: Insert a single attribute into the department with the code d50
insert node (attribute pais{'ES'},attribute tele{'938030000'})
as last into doc('/Practica/economia/empresa.xml')//dept[@codi='d50']
❗Because we are inserting into a node that exist we use the ((as (first | last))? into)
syntax.
Insert - One or more attributes/nodes into one or more
nodes
If the insertion(one or more nodes/attributes) into one or more nodes then FLOWR
should be used
for $n in onInserir return
insert (node | nodes) (seqüènciaAtributs, seqüènciaNodes)
((as (first | last))? into) | after | before $n
If the insertion is only into one node then the following
BASEX XML DATABASE 3
insert (node | nodes) (seqüènciaAtributs, seqüènciaNodes)
((as (first | last))? into) | after | before onInserir
EXAMPLE: Insert a single attribute and node
insert node (attribute fax{'938040000'},
<adreça><carrer>Av. Emili Vallès, 4</carrer>
<cp>08700</cp>
</adreça>)
after doc('/Practica/economia/empresa.xml')//dept[@codi='d50']/localitat
❗ When inserting an attribute and a node into a node we just put the both of
them in a single parenthesis,and use the after like we inserting a node and put
the location at the end because we inserting the new address node into the
location node. When inserting mutiple attributes and node it still follows the
structure and separate the attributes with a coma
insert node (
attribute fax {'938040000'},
attribute email {'[email protected]'},
<adreça>
<carrer>Av. Emili Vallès, 4</carrer>
<cp>08700</cp>
</adreça>,
<telefon>123456789</telefon>
)
after doc('/Practica/economia/empresa.xml')//dept[@codi='d50']/localitat
Rename - Name of attribute(s)/node(s)
In case of various the flowr can be done
BASEX XML DATABASE 4
for $n in nodeOAtributAReanomenar
return rename node $n as 'nouNom'
Also renaming can be done without for
rename node nodeOAtributAReanomenar as 'nouNom'
EXAMPLE: Change name of a node
rename node doc('/Practica/economia/empresa.xml')//dept/adreça as 'direccion
In our database since we have one only one node called adreca in the department
called adrca we can use the rename without FLOWR but if there are many in other
nodes that is the wrong way. The correct way is as follows.
for $n in doc('/Practica/economia/empresa.xml')//dept/direccion
return rename node $n as 'domicili'
EXAMPLE: Change attribute name
for $n in doc('/Practica/economia/empresa.xml')//dept/@tel
return rename node $n as 'telefon'
Replace Value - Substitute the value of
node(s)/attribue(s)
For the general purpose
for $n in nodeOAtributAReanomenar
return replace value of node $n with 'nouValor'
BASEX XML DATABASE 5
but in case the value is unique we can do without the for
replace value of node nodeOAtribut with 'nouValor'
EXAMPLE: Replace the value of a node
replace value of node doc('Practica/economia/empresa.xml')//dept[localitat='Igu
❗Make sure to choose the node specifically or else it will change all the nodes
Replace - Substitute node(s)/attribute(s)
for $n in nodeOAtributAReanomenar
return replace node $n with nouNodeONouAtribut
In case of a unique node or attribute
replace node nodeOAtribut with nouNodeONouAtribut
To indicate the new attribute the norm of the INSERT command should be
followed.
EXAMPLE: Replace a whole node
replace node doc('BD/economia/empresa.xml')//dept[nom="RRHH"]with
<dept codi="d99"><nom>Festes</nom><localitat>Marbella</localitat></dept>
Delete- node(s)/attribute(s)
BASEX XML DATABASE 6
delete node nodeOAtributAEliminar
for $n in nodeOAtributAEliminar
return delete node $n
Example: Delete A Node
delete node doc('BD/economia/empresa.xml')//dept[nom]
BASEX JAVA API
Exercise Questions
Connection To BaseX Server
ClientSession connection = new ClientSession(host,port,user,password)
Disconnecting From The BaseX Server
To disconnect from basex the connection class has the close method that
disconnects the client from the server.
connection.close();
BASEX XML DATABASE 7
BaseX API properties Files
In baseX, the ClientSession needs four arguments to be passed to establish
connection with the database. Hence in the properties file the four essesntial
properties are:
Host of the database
Port of tthe database server
Username of a db admin
Password of a db admin
Queries In BaseX
To make queries in BaseX the ClientQuery class is used where you inject the
current connection to it by means of connection.query() .
To execute a query passed into the clientquery by the connection the clientquery
has the execute() method that returns the query result from the Db
After each query the clientquery should be closed to release resources through
the close() method
ClientQuery q = connection.query(query);
String result = q.execute();
removing employee in basex
public void eliminarEmpleat(int codi, int actCap) {
if (!existeixEmpleat(codi)) {
throw new EPBaseXException("Intent d'eliminar empleat amb codi " + cod
}
if (codi == actCap) {
BASEX XML DATABASE 8
throw new EPBaseXException("Intent d'eliminar empleat amb codi " + cod
+ " reassignant els seus subordinats a ell mateix ");
}
if (actCap < 0) {
throw new EPBaseXException("S'ha invocat mètode eliminarEmpleat amb
}
// Sabem que l'empleat a eliminar existeix
String cad = null;
if (actCap == 0) {
/* Deixar els subordinats sense cap i eliminar l'empleat */
// Instrucció per eliminar dels subordinats, l'atribut "cap":
cad = "delete node " + path + "//emp[@cap='e" + codi + "']/@cap";
cad = cad + ",";
// Instrucció per eliminar el propi empleat
cad = cad + "delete node " + path + "//emp[@codi='e" + codi + "']";
// cad conté la seqûència d'instruccions per deixar els subordinats sense
// i eliminar l'empleat
} else {
/* Hem d'intentar substituir el cap dels subordinats (pot ser que no n'hi ha
if (!this.existeixEmpleat(actCap)) {
throw new EPBaseXException("Intent d'eliminar empleat amb codi " + c
+ " reassignant els seus subordinats a empleat de codi " + actCap
}
if (this.esSubordinatDirecteIndirecte(codi, actCap)) {
throw new EPBaseXException("Intent d'eliminar empleat amb codi " + c
+ " reassignant els seus subordinats a empleat de codi " + actCap
+ " que és un subordinat (directe o indirecte) del cap");
}
/* Cal canviar el cap als subordinats directes i eliminar l'empleat */
// cad = "replace value of node " + path
// + "//emp[@cap='e" + codi + "']/@cap with 'e" + actCap + "'\n";
// La instrucció anterior només funcionaria quan ha de canviar el valor de l'a
// en un ÚNIC node!!!
// Com que pot ser en varis nodes (depèn dels subordinats de l'empleat, ca
cad = "for $n in " + path + "//emp[@cap='e" + codi + "']\n"
+ "return replace value of node $n/@cap with 'e" + actCap + "'\n";
BASEX XML DATABASE 9
cad = cad + ",";
// Instrucció per eliminar el propi empleat
cad = cad + "delete node " + path + "//emp[@codi='e" + codi + "']";
// cad conté la seqûència d'instruccions per canviar el cap als subordinats
// i eliminar l'empleat
}
ClientQuery q = null;
try {
q = con.query(cad);
q.execute();
hmEmp.remove(codi);
Collection empleats = hmEmp.values();
Iterator<Empleat> iteEmp = null;
if (actCap == 0) {
// Cal eliminar el cap als possibles subordinats existents en memòria
iteEmp = empleats.iterator();
// ALERTA! Dins "else" següent, explicat per què NO es pot referenciar
while (iteEmp.hasNext()) {
Empleat e = iteEmp.next();
if (e.getCap() != null && e.getCap().getCodi() == codi) {
e.setCap(null);
}
}
} else {
// Cal actualitzar el cap als possibles subordinats existents en memòria
// Primer cal tenir la referència que apunta al nou cap
Empleat nouCap = getEmpleat(actCap);
// En cas que actCap no hagués estat en memòria, el mètode getEmple
// I Java NO permet recórrer un iterator d'un HashMap que hagi estat c
// Es genera una ConcurrentModificationException!!!
iteEmp = empleats.iterator();
while (iteEmp.hasNext()) {
Empleat e = iteEmp.next();
if (e.getCap() != null && e.getCap().getCodi() == codi) {
e.setCap(nouCap);
}
BASEX XML DATABASE 10
}
}
} catch (Exception ex) {
throw new EPBaseXException("Problema en intentar eliminar empleat amb
} finally {
tancarQuery(q);
}
Let's break this method eliminarEmpleat into digestible parts to explain the logic
clearly, focusing on the actCap == 0 case and the else block.
Context of the Method
This method removes an employee ( empleat ) identified by a code ( codi ) from some
data storage system while handling:
1. Reassignment of subordinates (if any).
2. Error-checking for invalid operations.
Parameters:
codi : The unique identifier of the employee to remove.
: The new manager for the employee's subordinates, or
actCap 0 to leave
subordinates without a manager.
Case: actCap == 0
When actCap == 0 , the subordinates of the employee being removed are left without
a manager. Here’s what happens:
BASEX XML DATABASE 11
1. Remove the subordinates' cap (manager):
The instruction:
llCad.add("update delete " + path + "//emp[@cap='e" + codi + "']/@cap");
removes the cap attribute from all subordinates of the employee identified by
codi . This means those subordinates no longer have a manager.
2. Delete the employee:
The instruction:
llCad.add("update delete " + path + "//emp[@codi='e" + codi + "']");
deletes the employee record from the storage system.
3. Update in-memory subordinates:
After executing the updates on the data store, the code iterates over in-
memory employee objects and removes references to the removed employee (
codi ) as their manager:
while (iteEmp.hasNext()) {
Empleat e = iteEmp.next();
if (e.getCap() != null && e.getCap().getCodi() == codi) {
e.setCap(null);
}
}
This ensures the in-memory model matches the database changes.
Case: else (Reassigning a new manager)
If actCap > 0 , the subordinates of the employee being removed are reassigned to a
new manager ( actCap ). The steps are:
1. Validation:
Ensure the new manager ( actCap ) exists:
BASEX XML DATABASE 12
if (!this.existeixEmpleat(actCap)) {
throw new EPSednaException(...);
}
Prevent circular hierarchy:
if (this.esSubordinatDirecteIndirecte(codi, actCap)) {
throw new EPSednaException(...);
}
2. Reassign subordinates to the new manager:
The instruction:
llCad.add("update replace $n in " + path + "//emp[@cap='e" + codi + "']/
@cap\n"
+ "with (attribute cap {'e" + actCap + "'})");
replaces the cap attribute of subordinates previously managed by codi to now
point to actCap .
3. Delete the employee:
Similar to the
actCap == 0 case:
llCad.add("update delete " + path + "//emp[@codi='e" + codi + "']");
4. Update in-memory subordinates:
Reassign the
cap attribute of in-memory subordinates to the new manager:
Empleat nouCap = getEmpleat(actCap);
while (iteEmp.hasNext()) {
Empleat e = iteEmp.next();
if (e.getCap() != null && e.getCap().getCodi() == codi) {
e.setCap(nouCap);
BASEX XML DATABASE 13
}
}
Summary of the actCap == 0 vs. else Logic
actCap == 0 : Subordinates are left without a manager.
The cap attribute is removed from the database and in-memory
subordinates.
else : Subordinates are reassigned to a new manager.
The cap attribute is updated in the database and in-memory subordinates
to point to the new manager.
If any validations fail, exceptions are thrown to ensure data consistency and to
prevent logical errors like circular references.
BASEX XML DATABASE 14