2011-08-17 14 views
11

Para ajustarse al <boolean>spec of Xml-RPC necesito transformar mi xs:boolean de true|false a 1|0.¿Cómo controlar la interpretación booleana en XSLT

Solucioné esto utilizando XSL: elegir

<xsl:template match="Foo"> 
    <member> 
     <name>Baz</name> 
     <value> 
      <boolean> 
       <xsl:choose> 
        <xsl:when test=".='true'">1</xsl:when> 
        <xsl:otherwise>0</xsl:otherwise> 
       </xsl:choose> 
      </boolean> 
     </value> 
    </member> 
</xsl:template> 

pero preguntaba si hay una manera menos frágil de controlar cómo se representan valores booleanos cuando se transforma con XSLT 1.0.

+0

Buena pregunta, 1. Vea mi respuesta para una solución completa, corta y fácil (un XPath one-liner). :) –

Respuesta

15

Uso:

number(boolean(.)) 

Por la definición de la función XPath estándar number() produce exactamente {0, 1} cuando se aplican, respectivamente, en {true(), false()}

¡Cuidado! Si utiliza esta construcción en strings, el resultado será verdadero para 'falso' y 'verdadero', porque, para los parámetros de cadena, boolean() is true if and only if its length is non-zero.

lo tanto, si desea convertir cadenas, no booleanos, a continuación, utilizar esta expresión:

number(not(. = 'false')) 

A continuación se muestra una verificación basada en XSLT:

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

<xsl:template match="node()|@*"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="text()"> 
    <xsl:value-of select="number(not(. = 'false'))"/> 
</xsl:template> 
</xsl:stylesheet> 

cuando esta transformación se aplica en el siguiente documento XML:

<t> 
<x>true</x> 
<y>false</y> 
</t> 

el, resultado correcto querido se produce:

<t> 
    <x>1</x> 
    <y>0</y> 
</t> 
+0

Excelente siempre, pero mi número de versión preferido (booleano (.)) No parece funcionar ... siempre devuelve '1'. Iré por la comparación de cadenas que me permitirá usar una plantilla más genérica en mi solución. – Filburt

+0

Parece que 'number (boolean ('false'))' devolverá '1', mientras que' number (boolean (false)) 'devolverá' 0' así que la pregunta restante para la felicidad final es cómo recuperar el valor no literal de un xs: elemento booleano ;-) – Filburt

+0

@Filburt: en caso de que realmente tenga un booleano, utilice: 'number (.)'. La razón por la que aún hay preguntas pendientes es que no ha proporcionado un documento XML completo y el resultado completo deseado. Cuando la gente adivina esto, incluso una tasa de éxito del 10% es enorme. –