sintaxis XSLT y XPath> cómo hacer referencia a un elemento en un ámbito 'exterior'

StackOverflow https://stackoverflow.com/questions/1843693

  •  12-09-2019
  •  | 
  •  

Pregunta

Tengo el siguiente trabajo 100% correctamente. Sin embargo, para satisfacer mi curiosidad ... ¿hay una manera de lograr lo mismo sin declarar la variable currentID? ¿Hay alguna manera de hacer referencia a ella desde el interior de la "prueba" condición XPath?

La consulta XPath en la condición debe referirse a 2 @id atributos para ver si coinciden.

  • la 'corriente' @Id
  • cada uno 'antepasado' @Id

Aquí está el código:

<xsl:variable name="currentID" select="@id" />
<xsl:attribute name="class">
<xsl:if test="count($currentPage/ancestor::node [@id = $currentID])&gt;0">descendant-selected </xsl:if>
</xsl:attribute>
¿Fue útil?

Solución

Dado que se selecciona el $currentID desde el nodo de contexto:

<xsl:variable name="currentID" select="@id" />

Puede utilizar la función current(), que siempre se refiere al nodo de contexto XSLT:

<xsl:attribute name="class">
  <xsl:if test="count($currentPage/ancestor::node[@id = current()/@id) &gt; 0]">
    <xsl:text>descendant-selected </xsl:text>
  </xsl:if>
</xsl:attribute>

De esta manera no es necesario una variable.

Algunas otras notas:

  • Recomiendo el uso de <xsl:text> como se muestra arriba. Esto le da más libertad para dar formato a su código y evitar las líneas excesivamente largas.
  • No es necesario hacer un count() > 0, simplemente seleccionando los nodos es suficiente. Si no existe ninguna, el conjunto de nodos vacío se devuelve. Siempre se evalúa como falsa, mientras que no estén vacíos conjuntos de nodos siempre como resultado true.

Si se hace referencia a nodos mediante @id regularmente en su hoja de estilo XSL, un <xsl:key> llegaría a ser beneficiosa:

<xsl:key name="kNodeById" match="node" use="@id" />

<!-- ... -->

<xsl:attribute name="class">
  <xsl:if test="key('kNodeById', @id)">
    <xsl:text>descendant-selected </xsl:text>
  </xsl:if>
</xsl:attribute>

Lo anterior no necesita current() ya que fuera de un predicado XPath, el contexto ha cambiado. También, no count() los nodos, ya que esto es redundante (como se explica).

Otros consejos

uso actual () para referirse al nodo actual procesada por la plantilla:

<xsl:if test="count($currentPage/ancestor::node [@id = current()/@id])&gt;0">

Tim me hizo pensar .... Creo que tenía más de complicar las cosas, y he intentado lo siguiente, que funciona.

<xsl:if test="@id = $currentPage/ancestor::node/@id">descendant-selected </xsl:if>

XSLT parece feliz comparar un atributo con una selección de atributos, y la evaluación de cierto si cualquiera de ellos partido? si alguien tiene una mejor explicación de por qué esto funciona o algo mejor (más breve) y luego lo dejó.

Como ya ha quedado claro, en referencia al "ámbito exterior" no era un problema, ya que es posible hacer una comparación directa con el operador "=". Sin embargo, hay algunos casos en los que sí es necesario actual (y más), además de que incluso actual () no es suficiente (porque es necesario para "unir" entre más de sólo dos contextos). En esos casos, XPath 2.0 "por" expresiones son indispensables.

Simplemente podría hacer:

<xsl:if test="count($currentPage[ancestor::node/@id = @id])&gt;0">descendant-selected </xsl:if>
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top