2010-05-14 14 views
7

Estoy seguro de que esta es una pregunta extremadamente básica, ¡pero aquí va de todos modos! He leído que el construido en la regla de plantilla para el texto y atribuir los nodos en XSLT esXSLT Plantilla incorporada Reglas para los atributos

<xsl:template match="text()|@*"> 
    <xsl:value-of select="."/> 
</xsl:template> 

Sin embargo, para el documento de origen

<?xml version="1.0"?> 
<booker> 
<award> 
    <author blah="test">Aravind Adiga</author> 
    <title>The White Tiger</title> 
    <year>2008</year> 
</award> 
</booker> 

y XSLT

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

Me da la siguiente salida aplicando la transformación en Visual Studio. ¿Puede alguien explicar por qué no veo "prueba" en la salida?

Aravind Adiga

El Tigre Blanco

Respuesta

6

Debido a la regla integrada por elementos no se aplica plantillas para propios atributos de un elemento, sólo es elementos secundarios. Si desea atravesar los atributos de la misma manera que atraviesan los elementos secundarios (que es probablemente una tarea artificial) es necesario definir su propio defecto:

<xsl:template match="*"> 
    <xsl:apply-templates select="@*"/> 
    <xsl:apply-templates/> 
</xsl:template> 
+1

Acepto, solo para agregar para compleción, el valor predeterminado '' selecciona todos los nodos secundarios, no solo los elementos (de lo contrario, el código de la pregunta no arrojaría nada). – Krab

+0

Gracias, no necesito hacerlo, solo intento entender las reglas. Entonces, básicamente, ¿la parte '@ *' de la regla incorporada nunca será invocada a menos que se llame explícitamente? –

6

Para abordar esta cuestión desde un comentario:

Gracias, no necesito hacerlo, solo intento entender las reglas. Entonces, básicamente, la parte @ * de la regla incorporada nunca se invocará a menos que se llame explícitamente.

En este caso, hay dos reglas por defecto que nos interesan:

<xsl:template match="text()|@*"> 
    <xsl:value-of select="."/> 
</xsl:template> 

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

Cuando se procesa el documento, el segundo encaja con la raíz y se aplica a las plantillas. El valor predeterminado para apply-templates es seleccionar todos los nodos secundarios (los atributos, confusamente, no son nodos secundarios). Nunca seleccione ningún atributo para ser procesado, ya que el único apply-templates aparece en su forma predeterminada.

Así que si seleccionó en algún lugar cualquier atributo (como lo hizo Vincent Marchetti), sería procesado por la primera plantilla predeterminada mencionada.

+0

+1 ¡Ya veo! Gracias, todo tiene sentido ahora. –

2

La regla principal es: los atributos no tienen identidad en absoluto; solo se puede acceder a ellos como bits oblicuos unidos a un nodo. Es bueno pensar en ellos como inexistentes hasta que tengas un nodo primero. También puede pensar en ellos como ciudadanos de segunda clase en el mundo XPath y XSLT. Cada vez que los usa en condiciones de selección, es como cambiar de una unión a un cursor en SQL y cada vez que usa "para" en lugar de "aplicar", también sucede lo mismo.

Otra forma de decirlo: el único "índice" real y eficiente que tiene es el que tiene todas las XPaths en un documento (.Net en realidad crea Hashtable de XPaths => coincidencia de tiempo constante). El motivo por el que se "privilegia" la aplicación es que garantiza un procesamiento funcional puro: puede ejecutar todo lo que coincida mediante la aplicación en subprocesos separados sin sincronización y sin compartir la memoria; solo obtendrá sus resultados.

Tercera forma de verlo, lo cual es una exageración, imagine que sus etiquetas son tablas SQL y que solo tiene PK-s y FK-s sustitutos, nada más que pueda seleccionar realmente, excepto "todos de T1 y todos relacionado con ellos desde T2 ". Para cualquier motor SQL decente es como un esfuerzo de 0 costos para hacerlo: simplemente lee un buen ítem por ítem ya que la estructura del mismo es 1-1 con su consulta. Todo lo demás cuesta mucho más.

Una vez que haya seleccionado las etiquetas y las plantillas coincidan y se ejecuten, entonces es barato simplemente obtener los valores de los atributos, siempre y cuando solo los transforme/renderice. Las pruebas de Attrib al final de XPath también son razonablemente económicas, una vez más, ya que se seleccionó la etiqueta/nodo final y ahora solo queda un pequeño filtro en la parte superior.

Por lo tanto, el motor XSLT y la selección de XPath en general tienen una muy buena razón para ignorar por completo los atributos - perf.

Cuestiones relacionadas