Alcune cose che renderanno la comprensione delle risposte che diventa più facile:
In primo luogo, nodi e gli elementi non sono la stessa cosa. Gli elementi sono nodi, ma i nodi non sono necessariamente elementi. Spesso si trovano persone che usano i termini in modo intercambiabile. Esistono in realtà quattro tipi di nodi in XML: elementi, nodi di testo, istruzioni di elaborazione e commenti. (Gli attributi non sono in realtà nodi, che verranno visualizzati in un secondo.)
In XSLT, la radice di un documento XML non è il suo elemento di livello superiore; la radice è un'astrazione che in realtà non esiste. L'elemento di livello superiore è figlio della radice.Per esempio, ecco un documento XML ben formato la cui radice ha cinque nodi secondari, tra cui l'elemento di livello superiore:
<?xml-stylesheet href="mystyle.css" type="text/css"?>
<!-- this is a perfectly legitimate XML document -->
<top_level_element/>
Five? Sembra che ce ne siano solo tre. Penso che ti permetterò di capire cosa sono gli altri due. Suggerimento: in questo esempio potrebbero esserci in realtà sette nodi.
L'espressione XPath /
trova la radice del documento, non l'elemento di livello superiore. Nel caso precedente, per trovare l'elemento di livello superiore, devi utilizzare /top_level_element
o /*
. (E 'sempre sicuro da usare /*
di trovare l'elemento di livello superiore, dal momento che la radice del documento deve avere un unico elemento figlio.)
Quindi armati di questa conoscenza, diamo un'occhiata a ciò che apply-templates
fa. Fondamentalmente esegue un processo in due fasi: in primo luogo, costruisce un insieme di nodi. Quindi, e per ognuno, trova un modello corrispondente (tra i modelli nel file XSLT) e applica il modello ad esso. Come hai osservato in uno dei tuoi commenti, è concettualmente molto simile a un ciclo.
L'attributo select
viene utilizzato nel primo passaggio. Fornisce un'espressione XPath che viene utilizzata per creare il set di nodi a cui applicherà i modelli. Se non viene fornito alcun attributo select
, l'elenco che crea è tutto figlio del nodo contesto. (Il "nodo contesto" è il nodo a cui viene applicato il modello corrente.)
L'attributo match
sugli elementi template
viene utilizzato nel secondo passaggio. Il processore del foglio di stile trova tutti i modelli il cui attributo match
corrisponde al nodo al quale sta tentando di applicare i modelli. Se ne trova più di uno, seleziona il più specifico possibile, ad es. dato questi modelli:
<xsl:template match="*"/>
<xsl:template match="foo"/>
<xsl:template match="foo[bar]"/>
un elemento foo
con un elemento bar
bambino sarà compensato dal terzo, un elemento foo
senza bar
sarà compensato dal secondo, e un elemento di baz
sarà accompagnata da prima. (Il metodo effettivo che utilizza XSLT è definito here, in pratica, ho usato XSLT per quasi un decennio e non ho mai una volta bisogno di sapere precisamente come funziona, anche se è interessante.)
Se non trovare una corrispondenza, verrà utilizzato il modello predefinito built-in per il tipo di nodo - in fondo, si può presumere che qualsiasi trasformazione XSLT implicitamente contiene questi modelli:
<xsl:template match="*">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="text()">
<xsl:copy/>
</xsl:template>
<xsl:template match="processing-instruction() | comment() | @*"/>
armati di tutte queste conoscenze, ora puoi capire la trasformazione dell'identità:
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
Corrisponde a qualsiasi nodo o attributo (si noti che gli attributi non sono nodi, motivo per cui è necessario @*
), lo copia e quindi applica i modelli a tutti i relativi nodi figlio e attributi. (Solo la radice e gli elementi del documento avranno nodi figli, e solo gli elementi avranno attributi.) Poiché è l'unico modello nella trasformazione e soddisfa tutti i nodi e gli attributi, si applica a tutti i nodi e gli attributi figlio. Pertanto, copia tutto nell'albero dei sorgenti nell'albero di output.
Se si aggiunge questo modello per l'identificazione di trasformare:
<xsl:template match="foo"/>
ora avete una trasformazione che le copie ogni nodo nell'albero dei sorgenti trannefoo
elementi - che secondo modello corrisponde foo
elementi (il primo fa anche questo, ma poiché l'attributo match
del secondo è più specifico, è quello che XSLT sceglie) e non fa nulla con loro.
Considerato tutto questo, le risposte alle tue domande specifiche:
<xsl:apply-templates>
applica i modelli per i figli del nodo di contesto.
I nodi corrispondenti non vengono "restituiti" nel passaggio 1; il processore XSLT trova un modello per ciascuno e lo applica.
In questo esempio, il nodo di contesto è la radice del documento, un nodo astratto di cui sono figli l'elemento di livello superiore e eventuali commenti o istruzioni di elaborazione al di fuori di esso.
L'istruzione "Gli attributi non sono realmente nodi" non è corretta. Gli attributi sono nodi, ma gli attributi non sono figli dell'elemento. Per maggiori dettagli, vedi la mia risposta qui sotto. esegue solo modelli per i bambini (asse child: :) ma non per attributi (attributo asse: :) –