2010-03-21 41 views
6

Tengo un documento que se ve algo como¿Puedo construir esta consulta XPath de forma dinámica en XSLT?

<root> 
    <element> 
     <subelement1 /> 
     <subelement2 /> 
    </element> 
    <element> 
     <subelement2 /> 
     <subelement1 /> 
    </element> 
</root> 

En mi hoja XSLT en el contexto de /element[2]/[someNode] Quiero conseguir un número que representa la distancia de /element[1]/[someNode] (es decir, el número de hermanos anteriores de /element1/[someNode]). Por ejemplo, en el contexto de /element[2]/subelement1 me gustaría tener alguna forma de obtener el número 2, la distancia de /element[1] a /element[1]/subelement2. Solo necesito la distancia del nombre de nodo dado desde la primera instancia de <element>.

Intuitivamente pensé que podía construir esto como

<xsl:variable name="nodename" select="name()" /> 
<xsl:value-of select="/element[1]/$nodename/preceding-sibling::*" /> 

pero desafortunadamente esta hoja no se compila. ¿Lo que intento lograr es posible en XSLT?

+0

Su ejemplo parece inconsistente: en el contexto de '/ element [2]/[someNode]' quieres encontrar '/ element [1]/[someNode]' con un ejemplo en '/ element [2]/subelement1' quieres encontrar el distancia de '/ element [1]' a '/ element [1]/subelement 2' - ¿entonces es [algúnNodo] aquí subelemento2 o subelemento1? –

+0

Véase también http://stackoverflow.com/questions/4630023/dynamic-xpath-in-xslt – Vadzim

Respuesta

8
  1. No puede utilizar una variable XSLT como el eje de un XPath declaración, pero puede usarla en un filtro de predicados. Entonces, si tuviera que coincidir en cualquier elemento (es decir, *) y luego restringirlo a elementos cuyo nombre() es igual al valor almacenado en su variable (es decir, *[name()=$nodename]), el XPATH será válido.

  2. El XPATH que estaba construyendo devolvería el valor del elemento coincidente. Si desea devolver cuántos elementos coinciden con ese patrón, puede usar la función count().

  3. Su XML de ejemplo tiene un elemento de documento <root>, pero su XPATH no incluye <root>.

Esto devuelve el número de elementos-hermano precedente utilizando la variable asignada por el nodo de contexto:

<xsl:variable name="nodename" select="name()" /> 
<xsl:value-of select="count(/root/element[1]/*[name()=$nodename]/preceding-sibling::*)" /> 

Se podría eliminar la variable y el uso justo:

<xsl:value-of select="count(/root/element[1]/*[name()=name(current())]/preceding-sibling::*)" /> 
1

*[name() = $nodename] puede ser lo que desee en lugar de $nodename, pero entonces debería definir mejor dos variables con el valor de nombre-local() y espacio de nombres-uri() y comprobar, p. *[local-name() = $localname and namespace-uri() = $namespaceuri] para tener una forma segura de seleccionar elementos.

0

Build xpath's desafortunadamente es imposible. XPaths están compilados estáticamente; no puede generarlos sobre la marcha (o si lo hace, solo son cadenas y no se pueden ejecutar).

Sin embargo, lo que puede hacer es escribir una consulta que le sucede a referencias cruzadas de varios valores que a su vez son dinámicos ...

Cuestiones relacionadas