Si el documento XML de origen tiene su propio espacio de nombres, es necesario declarar el espacio de nombres en la hoja de estilos, asignarle un prefijo, y utilizar ese prefijo cuando se refiere a la elementos del XML de origen - por ejemplo:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xhtml="http://www.w3.org/1999/xhtml">
<xsl:output method="xml" encoding="utf-8" indent="yes" omit-xml-declaration="yes" />
<!-- identity transform -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<!-- exception-->
<xsl:template match="xhtml:property/@type">
<xsl:attribute name="type">
<xsl:text>some new value</xsl:text>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
O, si lo prefiere:
...
<!-- exception-->
<xsl:template match="@type[parent::xhtml:property]">
<xsl:attribute name="type">
<xsl:text>some new value</xsl:text>
</xsl:attribute>
</xsl:template>
...
Adición: En el caso muy poco probable que el espacio de nombres XML no se sabe de antemano, que podía hacer:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="utf-8" indent="yes" omit-xml-declaration="yes" />
<!-- identity transform -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<!-- exception -->
<xsl:template match="*[local-name()='property']/@type">
<xsl:attribute name="type">
<xsl:text>some new value</xsl:text>
</xsl:attribute>
</xsl:template>
Por supuesto, es muy difícil imaginar un escenario en el que lo haría sepa de antemano que el documento XML fuente contiene un elemento llamado "propiedad", con un atributo llamado "tipo" que necesita ser reemplazado, pero que todavía no conoce el espacio de nombre del documento. He agregado esto principalmente para mostrar cómo su propia solución podría ser optimizada.
Para aquellos que quieren una solución general: algún valor nuevo aquí xsl: attribute> xsl: template> xsl: template> xsl: stylesheet> –
astonia
Su solución es innecesariamente prolija, y parcialmente errónea. Debería haber '' http: // www.'' al principio del espacio de nombres 'xsl'. Además, hacer coincidir/seleccionar 'node() | comment() | processing-instruction() | text()' es superfluo, ya que los comentarios, las instrucciones de procesamiento y los nodos de texto se corresponden con 'node()'. – Flynn1179
@ Flynn1179 Mi solución funciona bien para todas las situaciones. No sé por qué http: // falta después de copiar/pegar, eso es un error, gracias por señalar. Acabo de dar una posible solución, no la perfecta. Lo más importante es que mi solución funciona para casi todas las situaciones, aunque "es superfluo" como dijiste. Mientras que, por otro lado, la mayoría de las otras respuestas, incluida la que dio "el experto xslt", no funcionan en absoluto. Pero ellos no lo admitieron. – astonia