2011-07-22 24 views
7

Yo soy muy novato XSLT y tienen una tarea sencilla:XSLT: cambiar ciertos valores de los atributos

Supongamos que tengo el siguiente código XML:

<Element1> 
    <Element2 attr1="1"/> 
</Element1> 
<Element1 attr1="2"/> 
<Element1> 
    <Element2 attr1="2"/> 
</Element1> 

Quiero transformar el XML a la mismo XML con un cambio: todos los atributos llamados "attr1", sin importar dónde se encuentren, tienen que transformarse para que, por ejemplo, "1" sea "A" y "2" será "X", i. mi. a

<Element1> 
    <Element2 attr1="A"/> 
</Element1> 
<Element1 attr1="X"/> 
<Element1> 
    <Element2 attr1="X"/> 
</Element1> 

¿Cómo puedo lograr esto? ¡Gracias de antemano!

Respuesta

8

Puede definir caracteres para reemplazar y reemplazar caracteres, luego use translate. Puede utilizar esta XSLT:

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

    <xsl:variable name="in">12</xsl:variable> 
    <xsl:variable name="out">AX</xsl:variable> 

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

    <xsl:template match="@attr1"> 
     <xsl:attribute name="attr1"> 
      <xsl:value-of select="translate(., $in, $out)"/> 
     </xsl:attribute> 
    </xsl:template> 

</xsl:stylesheet> 

Otra forma:

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

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

    <xsl:template match="@attr1"> 
     <xsl:choose> 
      <xsl:when test=". = '1'"> 
       <xsl:attribute name="attr1"> 
        <xsl:text>A</xsl:text> 
       </xsl:attribute> 
      </xsl:when> 
      <xsl:when test=". = '2'"> 
       <xsl:attribute name="attr1"> 
        <xsl:text>X</xsl:text> 
       </xsl:attribute> 
      </xsl:when> 
     </xsl:choose> 
    </xsl:template> 

</xsl:stylesheet> 

<xsl:template match="@attr1"> coincidirá con todos los atributos attr1, a continuación, utilizando xsl:choose que crea valor apropiado para este atributo.

+0

Para dar cabida a la personalización en tiempo de ejecución, cambiar el 'XSL: variable' a' XSL : param'. –

8

No dijo lo que sucede cuando @ attr = 3, por ejemplo, de modo que existe una cláusula de otra manera para copiar el valor, si no es uno de los seleccionados.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:template match="@*|node()"> 
    <xsl:copy> 
    <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
</xsl:template> 
<xsl:template match="@attr1"> 
    <xsl:attribute name="attr1"> 
    <xsl:choose> 
     <xsl:when test=". = 1"> 
     <xsl:text>A</xsl:text> 
     </xsl:when> 
     <xsl:when test=". = 2"> 
     <xsl:text>X</xsl:text> 
     </xsl:when> 
     <xsl:otherwise> 
     <xsl:value-of select="." /> 
     </xsl:otherwise> 
    </xsl:choose> 
    </xsl:attribute> 
</xsl:template> 
</xsl:stylesheet> 
+0

¿Qué sucede si los valores deben obtenerse del exterior? ¿Cómo se puede usar un archivo de mapeo externo, que tendrá el mapeo '" 1 "->" A "y" 2 "->" X "'? – Amol

+0

@Amol, entonces puede configurar una búsqueda utilizando la [función clave] (http://www.w3schools.com/xsl/func_key.asp) haciendo referencia al documento externo. –

+0

Le pregunté a [this] (http://stackoverflow.com/questions/14065523/applying-templates-multiple-times-based-on-string-values-from-other-document) pregunta para obtener más claridad. – Amol

2

Otra forma, usando la función document:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:l="local" 
> 
    <xsl:output method="xml" indent="yes"/> 

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

    <xsl:template match="@attr1"> 
     <xsl:attribute name="attr1"> 
      <xsl:value-of select="document('')//l:item[l:in = current()]/l:out"/> 
     </xsl:attribute> 
    </xsl:template> 

    <xml xmlns="local"> 
     <item> 
      <in>1</in> 
      <out>A</out> 
     </item> 
     <item> 
      <in>2</in> 
      <out>X</out> 
     </item> 
    </xml> 

</xsl:stylesheet> 
+0

¿No sería más eficiente usar una búsqueda de tecla en el documento? –

0

XSLT por debajo del 2 versión funciona:

<xsl:output method="xml" indent="yes"/> 

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

    <xsl:template match="@attr1[.='1']"> 
     <xsl:attribute name="attr1"> 
      <xsl:value-of select="replace(.,'1','A')"/> 
     </xsl:attribute> 
    </xsl:template> 

    <xsl:template match="@attr1[.='2']"> 
     <xsl:attribute name="attr1"> 
      <xsl:value-of select="replace(.,'2','X')"/> 
     </xsl:attribute> 
    </xsl:template> 

</xsl:stylesheet> 
Cuestiones relacionadas