XPath con escenario de empresa con departamentos e empregados

De MediaWiki
Ir a la navegación Ir a la búsqueda

Enunciado

Partimos deste XML.

<?xml version="1.0" encoding="UTF-8"?>
<empresa> 
 <departamento cod_dep="cont">
  <telefono>981111111</telefono>
  <nome>contabilidade</nome>
  <empregado cod_emp="cont_001">
   <nome>Xose</nome>
   <dni>11111111A</dni>
   <salario>4100</salario>
  </empregado> 
 <empregado cod_emp="cont_002">
  <nome>Alba</nome>
  <dni>22222222B</dni>
  <salario>8100</salario>
 </empregado> 
</departamento> 

 <departamento cod_dep="publ">
  <telefono>982222222</telefono>
  <nome>publicidade</nome>
  <empregado cod_emp="publ_001">
   <nome>Xoana</nome>
   <dni>33333333C</dni>
   <salario>1200</salario>
  </empregado> 
  <empregado cod_emp="publ_002">
   <nome>Brais</nome>
   <dni>44444444D</dni>
   <salario>3100</salario>
  </empregado> 
 </departamento> 
</empresa>

Descritores do camiño - rutas absolutas e relativas

Debemos saber que os descritores do camiño:

  • Serven para seleccionar elementos que se atopan en certo camiño da árbore.
  • fórmanse nomeando etiquetas separadas por /
    • Se o descriptor comeza por / é un camiño desde a raiz
    • Se o descriptor comeza por // o camiño descrito pode comezar en calquera parte da árbore
    • ambos poden ser combinados

1. Selecciona a listaxe de todas as etiquetas nome de todos os empregados da empresa

/empresa/departamento/empregado/nome


Resultado:

<nome>Xose</nome> 
<nome>Alba</nome> 
<nome>Xoana</nome> 
<nome>Brais</nome>

2. Selecciona toda as etiquetas nome en calquer nivel de profundidade do documento.

//nome

Resultado:

Amosará tanto nomes de departamentos como de empregados:

<nome>contabilidade</nome> 
<nome>Xose</nome> 
<nome>Alba</nome> 
<nome>publicidade</nome> 
<nome>Xoana</nome> 
<nome>Brais</nome>

3. Proba:

//empregado/nome

Resultado:

O mesmo que no punto 1, xa que selecciona todos os nodos nome que son fillos do nodo empregado na árbore, partindo desde calquer punto

4. Selecciona o salario de tres xeitos distintos

Tres posibles expresións son:

  • /empresa/departamento/empregado/salario
  • //salario
  • /empresa//salario

Descritores do camiño - operador *

O asterisco (*) emprégase para nomear calquera etiqueta (úsase coma comodín).

5. Selecciona a listaxe de todas as etiquetas nome que se atopan a dous niveles de profundidade desde a raiz

/*/*/nome

Resultado:

Amosa só os nomes dos departamentos.

<nome>contabilidade</nome>
<nome>publicidade</nome>

6. Qué devolve a seguinte expresión?

/*/*/*/nome

Resultado:

<nome>Xose</nome> 
<nome>Alba</nome> 
<nome>Xoana</nome> 
<nome>Brais</nome>

Descritores do camiño - atributos

Úsase a @ para referirse os atributos. Nun descritor de camiño, os atributos noméanse coma se foran etiquetas fillas, pero antepoñendo o caracter @.

7. Selecciona os cod_dep dos departamentos da empresa

/empresa/departamento/@cod_dep

O atributo é tratado coma se fora un fillo do elemento departamento, e precedido do símbolo / e co símbolo @

Resultado:

cod_dep="cont"
cod_dep="publ"

Predicados - Filtrando conxuntos de nodos

As expresiones XPath permiten a selección de nodos nunha árbore XML. Co filtrado de expresións mediante predicados podemos seleccionar grupos de nodos que responden a criterios máis complexos, definindo o acceso aos nodos dun xeito máis preciso.

Cando un nodo se corresponde co predicado da expresión (cúmprese a condición do mesmo), éste pasará a formar parte do resultado. Se a condición non se cumpre excluirase o nodo del resultado.

Pódense empregar tamén funcións construidas (last, count, etc.) e expresións matemáticas (+, -, * div, etc.).

Además do filtrado mediante operadores relacionales e booleanos, es posible restrinxir a selección mediante una disposición en serie de predicados: os predicados en cascada, que funcionan coma unha superposición de filtros.

En primeiro lugar fíltrase un conxunto de nodos, que será a súa vez predicado, e así sucesivamente.

Finalmente, en ocasións pode ser preciso unir varios conxuntos de nodos (co pipe, "|", coa tecla Alt Gr e o número 1 do teclado).

8. Selecciona os nodos empregado para os que teñen un salario inferior a 4000

/empresa/departamento/empregado[salario<4000]

Resultado:

<empregado cod_emp="publ_001">
  <nome>Xoana</nome>
  <dni>33333333C</dni>
  <salario>1200</salario>
</empregado>
<empregado cod_emp="publ_002">
  <nome>Brais</nome>
  <dni>44444444D</dni>
  <salario>3100</salario>
</empregado>

9. Selecciona os nomes dos empregados do departamento co atributo cod_dep igual a publ

//departamento[@cod_dep='publ']/empregado/nome

Resultado:

<nome>Xoana</nome>
<nome>Brais</nome>

10. Selecciona os DNI do primeiro elemento departamento do documento

/empresa/departamento[1]/empregado/dni

Resultado:

<dni>11111111A</dni>
<dni>22222222B</dni>

11. Selecciona os nif dos empregados do penúltimo departamento

/empresa/departamento[last()-1]/empregado/dni

Resultado: O mesmo que no anterior, xa que no exemplo temos dous departamentos, o penúltimo é tamén o primeiro ;)

<dni>11111111A</dni>
<dni>22222222B</dni>

12. Selecciona os nomes dos empregados que teñen menos de cinco caracteres.

//empregado[string-length(nome) <5 ]/nome

Resultado:

<nome>Xose</nome>
<nome>Alba</nome>

13. Selecciona o nome dos empregados que comezan por X

//empregado[starts-with(nome,'X')]/nome

Resultado:

<nome>Xose</nome>
<nome>Xoana</nome>

14. Conta o número de departamentos do documento

count(//departamento)

Resultado: 2

15. Conta o número de empregados do documento

count(//empregado)

Resultado: 4

16. Selecciona o código de departamento dos que teñen menos de tres empregados

//departamento[count(empregado)<3]/@cod_dep

Resultado:

 cod_dep="cont"
 cod_dep="publ"

17. Selecciona os empregados do departamento de publicidade que cobren máis de 2000 e todos os empregados do departamento de contabilidade

//departamento[@cod_dep='publ']/empregado[salario>2000] | //departamento[@cod_dep='cont']/empregado

Eixos (axes) - sintaxe abreviada e non abreviada

Temos visto os descriptores de camiños que baixan pola árbore. En xeneral un camiño parte na raíz da árbore e logo executa unha secuencia de pasos para percorrer a árbore a atopar os nodoes que se precisan.

En cada paso se puede seguir unha de varias direccións (axes, eixos en galego). A dirección por defecto é child:: que significa seguir por calquera dos fillos do elemento actual.

Así:

  • a expresión /empresa/departamento é realmente unha forma abreviada da expresión /empresa/child::departamento . Esta última sintaxe expresa claramente o desexo de seguir polos fillos da empresa.
  • o símbolo @ é tam´´en unha abreviación da dirección attribute:: .
  • a expresión /empresa/departamento[@cod_dep='publ'] é unha forma abreviada desta outra expresión: /empresa/child::departamento[attribute::cod_dep='publ'].

Existen moitas outras direccións:

  • descendant:: para seleccionar os descendentes do nodo actual
  • descendant-or-self:: para seleccionar o nodo actual e todos os seus descendientes (// é a versión abreviada desta dirección)
  • ancestor:: para seleccionar todos os antepasados (pais, avós, etc.) do nodo actual
  • ancestor-or-self:: para seleccionar o nodo actual e todos os antepasados (pais, avós, etc.)
  • parent:: para seguir polos pais dun elemento
  • following, following-sibling, etc.

Tes no titorial de w3schools explicacións con exemplos.

17. Selecciona con sintaxe non abreviada o nome do departamento do empregado 22222222C

//empregado[nif='22222222C']/parent::node()/nome

Resultado:

<nome>contabilidade</nome>

18. Selecciona con sintaxe non abreviada a totalidade do nodo pai (departamento)

//empregado[nif='22222222C']/parent::node()/nome

19. Selecciona con sintaxe non abreviada os elementos nome descendentes do elemento empresa (serán no noso caso os nomes de departamentos e empregados)

/empresa/descendant::nome

Resultado:

<nome>contabilidad</nome>
<nome>Xose</nome>
<nome>Alba</nome>
<nome>publicidad</nome>
<nome>Xoana</nome>
<nome>Brais</nome>

20. Qué devolve a seguinte expresión?

//empregado[nome='Xoana']/following-sibling::empregado

Resultado:

<empregado cod_emp="publ_002">
  <nome>Brais</nome>
  <dni>44444444D</dni>
  <salario>3100</salario>
</empregado>

21. Qué devolve a seguinte expresión?

//empregado[nome='Xose']/preceding-sibling::empregado


Resultado:

Non atopará ningún resultado porque Xose é o primeiro.

Referencias