2011-01-30 45 views
26

Quiero dividir una dirección en punto y coma (;) en filas separadas por <br />:xsl: cómo dividir cadenas?

p. Si address = 123 Elm Street, quiero salida 123 Elm Street,

pero si address = 123 Elm Street;PO Box 222, quiero salida

123 Elm Street<br />PO Box 222 

y si address = 123 Elm Street;PO Box 222;c/o James Jones, quiero salida

123 Elm Street<br />PO Box 222<br />c/o James Jones 

Es Hay una manera de hacer esto? (Probablemente fácil, pero no estoy tan familiarizado con XSLT)

El selector XSL llanura es

<xsl:value-of select="address"/> 

y me gustaría modificar este fragmento de XSLT para dividir el punto y coma.


actualización: Al parecer la respuesta implica el uso de <xsl:call-template> y las funciones substring-before() y substring-after().

Pero soy un principiante de XSLT y realmente podría usar algo de ayuda sobre cómo hacerlo.

+0

posible duplicado de [¿El XSLT tener una función Split()?] (http://stackoverflow.com/questions/136500/does-xslt-have-a-split-function) – porges

+0

tal vez es casi duplicado, pero no sé cómo aplicar las respuestas a esa pregunta, a mi problema. –

+0

Vea también http://stackoverflow.com/questions/10750184/looping-through-multiple-sequences-from-strtokenize – Vadzim

Respuesta

52

I. Llanura XSLT solución 1,0:

Esta transformación:

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

<xsl:template match="text()" name="split"> 
    <xsl:param name="pText" select="."/> 
    <xsl:if test="string-length($pText)"> 
    <xsl:if test="not($pText=.)"> 
    <br /> 
    </xsl:if> 
    <xsl:value-of select= 
    "substring-before(concat($pText,';'),';')"/> 
    <xsl:call-template name="split"> 
    <xsl:with-param name="pText" select= 
    "substring-after($pText, ';')"/> 
    </xsl:call-template> 
    </xsl:if> 
</xsl:template> 
</xsl:stylesheet> 

cuando se aplica en este documento XML:

<t>123 Elm Street;PO Box 222;c/o James Jones</t> 

produce el resultado deseado, corregido:

123 Elm Street<br />PO Box 222<br />c/o James Jones 

II. FXSL 1 (para XSLT 1.0):

Aquí sólo tiene que utilizar el FXSL plantilla str-map (y no tener que escribir la plantilla recursiva por el momento 999a):

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:f="http://fxsl.sf.net/" 
xmlns:testmap="testmap" 
exclude-result-prefixes="xsl f testmap" 
> 
    <xsl:import href="str-dvc-map.xsl"/> 

    <testmap:testmap/> 

    <xsl:output omit-xml-declaration="yes" indent="yes"/> 

    <xsl:template match="/"> 
    <xsl:variable name="vTestMap" select="document('')/*/testmap:*[1]"/> 
    <xsl:call-template name="str-map"> 
     <xsl:with-param name="pFun" select="$vTestMap"/> 
     <xsl:with-param name="pStr" select= 
     "'123 Elm Street;PO Box 222;c/o James Jones'"/> 
    </xsl:call-template> 
    </xsl:template> 

    <xsl:template name="replace" mode="f:FXSL" 
     match="*[namespace-uri() = 'testmap']"> 
     <xsl:param name="arg1"/> 

     <xsl:choose> 
     <xsl:when test="not($arg1=';')"> 
     <xsl:value-of select="$arg1"/> 
     </xsl:when> 
     <xsl:otherwise><br /></xsl:otherwise> 
     </xsl:choose> 
    </xsl:template> 
</xsl:stylesheet> 

cuando esta transformación es aplicado en cualquier documento XML (no se utiliza), la misma, quería resultado correcto se produce:

123 Elm Street<br/>PO Box 222<br/>c/o James Jones 

III. Usando XSLT 2.0

<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="text()"> 
    <xsl:for-each select="tokenize(.,';')"> 
    <xsl:sequence select="."/> 
    <xsl:if test="not(position() eq last())"><br /></xsl:if> 
    </xsl:for-each> 
</xsl:template> 
</xsl:stylesheet> 

cuando se aplica esta transformación en este documento XML:

<t>123 Elm Street;PO Box 222;c/o James Jones</t> 

el resultado deseado, adecuados, se produce:

123 Elm Street<br />PO Box 222<br />c/o James Jones 
+0

¿podría explicar la sintaxis 'not ($ pText =.)'? ¿Qué está haciendo el '.'? –

+3

@ Jason-S: '.' en XSLT (y en XPath) significa el nodo actual (nodo de contexto). 'not ($ pText =.)' es 'true()' si el valor de la cadena del parámetro '$ pText' no es igual al valor de cadena del nodo actual - queremos generar'
'solo en este caso , de lo contrario, nuestra salida comenzará con '
' –

+0

¿Puedo pasar una variable ya existente a param name = "pText"? – Perdomoff

1

Si su procesador XSLT admite EXSLT, puede usar str:tokenize; de lo contrario, el enlace contiene una implementación que utiliza funciones como subserie-before.

+0

¿cómo me entero? Mi procesador XSLT es un navegador web, ya sea Firefox 3.6 o Safari 5.0 –

+2

@Jason S; en ese caso, no puede depender de eso y debe proporcionar la función usted mismo; la implementación está disponible en el enlace http://exslt.org/str/functions/tokenize/str.tokenize.template.xsl – Mormegil

+0

Aquí hay un ejemplo: http://stackoverflow.com/questions/10750184/looping-through- multiple-sequences-from-strtokenize – Vadzim

Cuestiones relacionadas