compreender a função posição() no XSLT

Tenho um problema semelhante a este tipo:

usar a função posição() no xslt

Mas não preciso da numeração, só quero entender como funciona.
<?xml version="1.0" encoding="UTF-8"?>
<test>
<a>blah</a>
<a>blah</a>
<a>blah</a>
<a>blah</a>
</test>

para esta entrada, a seguinte folha de estilo:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
  <html>
  <body>
<xsl:apply-templates/>
  </body>
  </html>
</xsl:template>

<xsl:template match="select">
<xsl:apply-templates/>
</xsl:template>

<xsl:template match="a">
<xsl:value-of select="position()"/><br/>
<xsl:apply-templates/>
</xsl:template>

</xsl:stylesheet>

saídas:

<html><body>
2<br>blah
4<br>blah
6<br>blah
8<br>blah
</body></html>
Porque é que salta os números irregulares?

 5
Author: hek2mgl, 2015-02-25

2 answers

Porque é que salta os números irregulares?
Porque enquanto estavas no nível, disseste:
<xsl:apply-templates/>

Que aplica modelos a todos os nós filhos do nó raiz, e (devido às regras de modelo incorporadas) a todos os seus descendentes - incluindo os nós de texto que separam os elementos <a> .

Você terá um resultado diferente com uma entrada de:

<?xml version="1.0" encoding="UTF-8"?>
<test><a>blah</a><a>blah</a><a>blah</a><a>blah</a></test>

Ou se adicionar uma instrução à sua folha de estilo to:

<xsl:strip-space elements="*"/>

Ou se aplicar modelos selectivamente, por exemplo

<xsl:apply-templates select="//a"/>
 4
Author: michael.hor257k, 2015-02-25 10:37:25

A função position() dá-Lhe a posição do nó actual dentro da "lista de nós actuais", que é o que for select - ed pela mais próxima apply-templates ou for-each (XSLT 2.0 refere-se a "itens" e "sequências" em vez de nós e listas de nós, mas o princípio é o mesmo).

No seu exemplo, o modelo root aplica modelos aos seus dois nós-filhos (o nó de texto que contém a quebra de linha após a declaração xml e o elemento test). Não há nenhuma regra explícita que corresponda a test por isso, aplica-se a regra por omissão, que para os elementos significa <xsl:apply-templates/>.

Assim, quando o modelo a dispara a sua "lista de nós actuais" é o conjunto de todos os 9 nós-filhos de test. Esta lista consiste em nós de texto alternados (as quebras de linha) e nós de elementos (OS Elementos a), com os nós de texto nas posições ímpares e os nós de elementos nas posições pares.

Se adicionou um modelo explícito para test Assim:

<xsl:template match="test">
  <xsl:apply-templates select="*"/>
</xsl:template>

Então isto iria seleccionar apenas {[25] } o 4 a nós de elementos como a lista de nós actual, por isso position() dar-lhe-ia 1, 2, 3 e 4.

 6
Author: Ian Roberts, 2015-02-25 10:02:09