2012-02-13 27 views
6

¿Cómo uso apply-templates para seleccionar solo esos elementos por nombre (no valor) que terminan con un patrón específico? Supongamos el siguiente código XML ...¿Cómo seleccionar elementos por parte de su nombre en XSL/XPath?

<report> 
    <report_item> 
    <report_created_on/> 
    <report_cross_ref/> 
    <monthly_adj/> 
    <quarterly_adj/> 
    <ytd_adj/> 
    </report_item> 
    <report_item> 
    .... 
    </report_item> 
</report> 

Quiero usar <xsl:apply-templates> en todas las instancias de <report_item> donde los elementos descendientes terminan con 'adj`, por lo que, en este caso, sólo monthly_adj, quaterly_adj y ytd_adj serían seleccionados y aplicado con la plantilla.

<xsl:template match="report"> 
    <xsl:apply-templates select="report_item/(elements ending with 'adj')"/> 
</xsl:template> 

Respuesta

10

No creo que la sintaxis de expresiones regulares está disponible en este contexto, incluso en XSLT 2.0. Pero no lo necesitas en este caso.

<xsl:apply-templates select="report_item/*[ends-with(name(), 'adj')]"/> 

* coincide con cualquier nodo

[pred] realiza una prueba de nodo contra el selector (en este caso *) (donde pred es un predicado evaluada en el contexto del nodo seleccionado)

name() rendimientos el nombre de la etiqueta del elemento (debe ser equivalente a local-name para este fin).

ends-with() es una función incorporada de cadena XPath.

+0

NUEVO RECORD MUNDIAL Stackoverflow .... más rápida respuesta siempre, LOL, tienes razón, no regulares, sólo simple 'termina with' fue suficiente, gracias. – raffian

+0

Me alegra ayudar :) He actualizado el título para que coincida mejor con la pregunta. – harpo

+0

Sí, estaba planeando actualizarme, ¡gracias de nuevo! – raffian

2

solución ligeramente más ordenado (XSLT 2.0 + solamente):

<xsl:apply-templates select="report_item/*[matches(name(),'adj$')]"/> 

Aquí es una auto-prueba para demostrar que funciona. (Probado en Saxon).

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       xmlns:fn="http://www.w3.org/2005/xpath-functions" 
       xmlns:xs="http://www.w3.org/2001/XMLSchema" 
       exclude-result-prefixes="xs fn"> 
<xsl:output method="xml" indent="yes" encoding="utf-8" /> 
<xsl:variable name="report-data"> 
    <report> 
    <report_item> 
    <report_created_on/> 
    <report_cross_ref/> 
    <monthly_adj>Jan</monthly_adj> 
    <quarterly_adj>Q1</quarterly_adj> 
    <ytd_adj>2012</ytd_adj> 
    </report_item> 
    </report> 
</xsl:variable> 
<xsl:template match="/" name="main"> 
    <reports-ending-with-adj> 
    <xsl:element name="using-regex"> 
    <xsl:apply-templates select="$report-data//report_item/*[fn:matches(name(),'adj$')]"/> 
    </xsl:element> 
    <xsl:element name="using-ends-with-function"> 
    <xsl:apply-templates select="$report-data//report_item/*[fn:ends-with(name(), 'adj')]"/> 
    </xsl:element> 
    </reports-ending-with-adj> 
</xsl:template> 
</xsl:stylesheet> 
+0

El 'match' funcionó para mí. Pero tengo un problema: http://xsltransform.net/pPzifp5/3 (me gustaría el orden de 'mOrder' para decir qué' li' me gustaría mostrar primero, segundo, tercero ...) Gracias. – Si8

+0

O algo como esto: http://xsltransform.net/pPzifp5/4 (Estoy buscando mostrar el padre LI y sub LI, pero se está multiplicando para cada iteración y duplicación. El LI vacío me gustaría no mostrar y solo mostrar si tiene un texto.) Gracias por la ayuda – Si8

+0

Publica una pregunta, y será respondida. –

Cuestiones relacionadas