XSLT e XPath sintaxe> como fazer referência a um elemento em um escopo 'exterior'

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

  •  12-09-2019
  •  | 
  •  

Pergunta

Eu tenho o seguinte a trabalhar 100% corretamente. No entanto, para satisfazer a minha curiosidade ... há uma maneira de conseguir o mesmo sem declarar a variável currentID? Existe alguma maneira para referenciá-lo a partir de dentro a condição XPath "teste"?

A consulta XPath na condição deve se referir a 2 atributos @ ID para ver se eles combinam.

  • o 'atual' @ id
  • cada 'ancestral' @ id

Aqui está o 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>
Foi útil?

Solução

Uma vez que você selecionar o $currentID a partir do nó de contexto:

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

Você pode usar a função current(), que sempre se refere ao nó 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>

Desta forma, você não precisa de uma variável.

Algumas outras notas:

  • Eu recomendo usar <xsl:text> como mostrado acima. Isto dá-lhe mais liberdade para formatar o seu código e evitar linhas excessivamente longas.
  • Você não precisa fazer um count() > 0, simplesmente selecionando os nós é suficiente. Se não existir nenhum, o vazio nó-conjunto é devolvido. É sempre avaliada como falsa, enquanto não vazios conjuntos de nós sempre avaliar como true.

Se você se refere a nós por @id regularmente em sua folha de estilo XSL, um <xsl:key> seria benéfico:

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

O current() acima não precisa desde fora de um predicado XPath, o contexto é inalterada. Além disso, eu não count() os nós, uma vez que este é redundante (conforme explicado).

Outras dicas

Use current () para se referir ao nó atual processado pelo template:

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

Tim me fez pensar .... Eu acho que eu estava sobre complicar as coisas, e eu tentei o seguinte que funciona.

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

XSLT parece feliz comparando um atributo com uma seleção de atributos, e avaliar verdadeiro se qualquer um deles combinar? se alguém tem uma melhor explicação de por que isso funciona ou algo melhor (mais sucinto), em seguida, colocá-lo para baixo.

Como já ficou claro, referindo-se ao "escopo externo" não era um problema, desde que você poderia fazer uma comparação direta usando o operador "=". No entanto, existem alguns casos onde você fazer necessidade atual () e mais além, onde até mesmo atual () não cortá-lo (porque você precisa para "juntar-se" entre mais do que apenas dois contextos). Nesses casos, XPath 2.0 "para" expressões são indispensáveis.

Você poderia simplesmente fazer:

<xsl:if test="count($currentPage[ancestor::node/@id = @id])&gt;0">descendant-selected </xsl:if>
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top