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.
Comentaris