Expressions XPath per nodes amb un namespace genèric en XSLT

Publicat el 17/04/2007

Quan es treballa amb un XML que conté un namespace genèric o per defecte cal tenir present que la selecció XPath des d'un XSL no és obvia.

Donat un XML tal que:


<ROOT>
   <A>
      <B/>
      <B/>
      <B>
         <C/>
      </B>
   </A>
</ROOT>

Per seleccionar els nodes B es podria usar un selector XPath tal que:


//B

Si afegim un namespace genèric a l'XML tal que:


<ROOT xmlns="urn:xyz">
   <A>
      <B/>
      <B/>
      <B>
         <C/>
      </B>
   </A>
</ROOT>

La selecció anterior (//B) no funcionarà ja que aquesta només selecciona nodes sense namespace definit.

Per seleccionar-los es poden emprar dues solucions. La primera és fer una selecció tal que:


//*[local-name()='B']

D'aquesta manera seleccionariem tots els nodes de tipus B. Però això pot dur problemes si es donés el cas d'un XML tal que:


<ROOT xmlns="urn:xyz" xmlns:bis="urn:abc">
   <A>
      <B/>
      <B/>
      <B>
         <C/>
      </B>
      <bis:X>
         <bis:B/>
      </bis:X>
   </A>
</ROOT>

Al fer la selecció seleccionariem tant els nodes B com els bis:B indistintament.

La segona solució passa per definir un prefix pel namespace a l'XSLT (sense manipular l'XML). És a dir, a l'XSL caldria fer quelcom tipus:


<xsl:stylesheet version="1.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:primari="urn:xyz"
   xmlns:bis="urn:abc">

En conseqüència el selector XPath incorporaria el prefix i quedaria en:


//primari:B

A l'XSLT 2.0, de recent publicació, s'ha pensat una via especialment pensada per fer aquest cas més obvi, explicada a l'apartat 5.2: Unprefixed QNames in Expressions and Patterns. Això no vol dir però, que les dues opcions anteriors deixin de ser vàlides.

Recursos relacionats

Comentaris

Afegir un comentari