2012-07-28 18 views
6

Me preguntaba si es posible usar analyze-string y configurar varios grupos dentro de RegEx y luego almacenar todos los grupos coincidentes en variables para usar más adelante.XSL Analyse-String -> Matching-Substring en múltiples variables

así:

<xsl:analyze-string regex="^Blah\s+(\d+)\s+Bloo\s+(\d+)\s+Blee" select="."> 
    <xsl:matching-substring> 
    <xsl:variable name="varX"> 
     <xsl:value-of select="regex-group(1)"/> 
    </xsl:variable>         
    <xsl:variable name="varY"> 
     <xsl:value-of select="regex-group(2)"/> 
    </xsl:variable>   
    </xsl:matching-substring> 
</xsl:analyze-string>  

Esto no funciona realmente, pero esa es la clase de cosa que estoy después, sé que puedo envolver el analyze-string en una variable, pero que parece tonto que por cada grupo Tengo que procesar el RegEx, no muy eficiente, debería poder procesar la expresión regular una vez y almacenar todos los grupos para usar más adelante.

¿Alguna idea?

Respuesta

6

Bueno hace

<xsl:variable name="groups" as="element(group)*"> 
<xsl:analyze-string regex="^Blah\s+(\d+)\s+Bloo\s+(\d+)\s+Blee" select="."> 
<xsl:matching-substring> 
    <group> 
    <x><xsl:value-of select="regex-group(1)"/></x> 
    <y><xsl:value-of select="regex-group(2)"/></y> 
    </group> 
</xsl:matching-substring> 
</xsl:analyze-string> 
</xsl:variable> 

ayuda? De esta manera tiene una variable llamada groups que es una secuencia de elementos group con las capturas.

+0

¿Cómo accedería a esos valores más adelante? Estoy acostumbrado a usar $ varname ¿Tiene acceso a esos como matrices? Necesito usar los valores más adelante en In test – TheStoneFox

+0

Puede acceder a '$ groups [1]/x',' $ groups [1]/y', '$ groups [2]/x',' $ groups [2 ]/y' y así sucesivamente. Por supuesto, también puede procesar los elementos más, por ejemplo. '' o apply-templates, p. ej. ''. –

+0

¡Esto funciona como un regalo, muchas gracias! – TheStoneFox

5

Esta transformación muestra que xsl:analyze-string no es necesario para obtener los resultados deseados: existe una solución más simple y genérica.:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:template match="*[matches(., '^Blah\s+(\d+)\s+Bloo\s+(\d+)\s+Blee')]"> 

    <xsl:variable name="vTokens" select= 
     "tokenize(replace(., '^Blah\s+(\d+)\s+Bloo\s+(\d+)\s+Blee', '$1 $2'), ' ')"/> 

    <xsl:variable name="varX" select="$vTokens[1]"/> 
    <xsl:variable name="varY" select="$vTokens[2]"/> 

    <xsl:sequence select="$varX, $varY"/> 
</xsl:template> 
</xsl:stylesheet> 

cuando se aplica en este documento XML:

<t>Blah 123 Bloo 4567 Blee</t> 

que produce el, resultado correcto deseada:

123 4567 

Aquí no nos basamos en el conocimiento el RegEx (se puede suministrar como parámetro) y la cadena; simplemente reemplazamos la cadena con un anuncio cadena eliminada de los grupos RegEx, que luego tokenize y cada elemento en la secuencia producida por tokenize() se puede asignar fácilmente a una variable correspondiente.

No tenemos que encontrar los resultados buscados enterrados a temp. árbol - acabamos de obtener todos en una secuencia de resultados.

+1

Muy eficiente, de hecho. +1 – conciliator

Cuestiones relacionadas