2010-09-06 16 views
7

Estoy tratando de transformar un archivo XML con el siguiente espacio de nombres, pero no pude encontrar una manera de hacerlo funcionar con el espacio de nombres predeterminado sin agregar un prefijo al XML de salida.XSLT transforma XML con el espacio de nombres predeterminado sin agregar prefijo?

archivo XML original:

<pExport xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://workflow.converga.com.au/compass"> 

que puede hacer que funcione mediante la adición de un prefijo para el espacio de nombres por defecto (el último), pero ¿cómo podría emitir una XML sin la adición de un prefijo, es posible gracias usando XslCompiledTransform en .NET 4?

+0

Parece que significa que * no * puede encontrar una forma de hacerlo funcionar con el espacio de nombres predeterminado sin agregar un prefijo al XML de salida. ¿De qué manera eso no funciona? ¿Cuál es el comportamiento observado cuando no agrega un prefijo? Etiquetaste esto con XSLT, ¿entonces quizás quieres decir que un procesador XSLT no reconoce el elemento pExport en el espacio de nombres del flujo de trabajo/brújula? Se necesita más información. Puede ser útil mostrar la parte relevante de su hoja de estilo. – LarsH

+0

Buena pregunta (+1).Vea mi respuesta para un ejemplo concreto y la solución utilizada. –

+0

LarsH, sí, lo que quise decir es que sin agregar prefijo, la salida XSLT no podría hacer coincidir los nodos con el espacio de nombres predeterminado (sin etiqueta). Estoy buscando una forma de unir estos elementos sin agregar mi propio prefijo para el espacio de nombres predeterminado. –

Respuesta

4

que puede hacer que funcione mediante la adición de un prefijo al espacio de nombres por defecto (el último), pero ¿cómo iba a emitir una XML sin agregar un prefijo, es posible mediante el uso XslCompiledTransform en. NET 4?

Aquí es un ejemplo concreto de cómo hacerlo:

Esta transformación:

<xsl:stylesheet version="1.0" 
xmlns="http://workflow.converga.com.au/compass" 
xmlns:c="http://workflow.converga.com.au/compass" 
xmlns:ext="http://exslt.org/common" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
exclude-result-prefixes="c ext xsl"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:param name="pnewItem"> 
    <item name="wine"> 
    <price>3</price> 
    <quantity>5000</quantity> 
    </item> 
</xsl:param> 

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

<xsl:template match="c:item[last()]"> 
    <xsl:call-template name="identity"/> 
    <xsl:copy-of select="ext:node-set($pnewItem)/*"/> 
</xsl:template> 
</xsl:stylesheet> 

cuando se aplica con XslCompiledTransform en el siguiente documento XML:

<pExport xmlns="http://workflow.converga.com.au/compass"> 
<Goods> 
    <item name="tobacco"> 
    <price>5</price> 
    <quantity>1000</quantity> 
    </item> 
</Goods> 
</pExport> 

produce el (el mismo documento XML con un nuevo elemento añadido) quería, resultado correcto:

<pExport xmlns="http://workflow.converga.com.au/compass"> 
    <Goods> 
    <item name="tobacco"> 
     <price>5</price> 
     <quantity>1000</quantity> 
    </item> 
    <item name="wine"> 
     <price>3</price> 
     <quantity>5000</quantity> 
    </item> 
    </Goods> 
</pExport> 
+0

Gracias, siguiendo su ejemplo, lo hice funcionar agregando espacio de nombres predeterminado adicional sin las opciones de prefijo y "exclude-result-prefixex". En realidad, no entiendo completamente tu código y cómo se supone que funcionan (ayer aprendí XSLT). Por ejemplo, ¿cuál es la sección en su primer bloque de código? –

+0

Una cosa menor, en el XML de salida el espacio de nombres predeterminado es siempre el primero, ¿podría cambiar eso al último, que es la posición del XML original? –

+0

@pstar: las especificaciones XSLT y XML W3C no imponen ningún orden específico para los atributos y los nodos de espacio de nombres. Su orden relativo es "dependiente de la implementación". Esto significa que, dependiendo del procesador XSLT concreto que esté utilizando, no tiene control sobre el orden de las declaraciones del espacio de nombres o, si tiene algún control, que esta "característica" no es portátil y no es compatible con otros procesadores XSLT. –

1

Simplemente necesita definir su espacio de nombres predeterminado en XSLT. Si también define uno con un prefijo, así que usted puede seleccionar los elementos de la entrada XML con facilidad:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://workflow.converga.com.au/compass" xmlns:compass="http://workflow.converga.com.au/compass"> 
    <xsl:template match="compass:pExport"> 
    <pExport>...</pExport> 
    ... 

La plantilla anterior coincidirá en contra de su elemento XML de entrada - y el elemento literal creado estará en el valor por defecto espacio de nombres de salida (que es el mismo espacio de nombres).

Por supuesto, debe tener en cuenta que en XML el prefijo es irrelevante: dos elementos son idénticos si tienen el mismo nombre y nombre local, incluso si los dos prefijos están definidos para ese espacio de nombres.

<element xmlns="http://test.com"></element> 
<ns01:element xmlns:ns01="http://test.com"></ns01:element> 

Los dos elementos anteriores son los mismos, ya que tienen el mismo nombre completamente calificado.

+0

para copiar el elemento coincidente con el mismo espacio de nombres, no necesita declarar un espacio de nombre predeterminado para el resultado, la instrucción 'copy' también funciona de esa manera. –

+0

Creo que tienes razón en el sentido de que el prefijo no debe afectar el espacio de nombres. Y tu solución funciona en ese sentido. Lo que estoy buscando es una solución sin agregar mi propio prefijo al espacio de nombres predeterminado. –

+0

El prefijo es irrelevante * en teoría *. En la práctica, algunos analizadores no son compatibles con el espacio de nombres, pero aún así desea generar el documento con un escritor que cumpla con los requisitos. Además, las especificaciones de algunas bases basadas en XML no usan ningún espacio de nombre. – dolmen

4

La clave es usar el atributo exclude-result-prefixes en el elemento stylesheet.

Hay algunas buenas explicaciones en this section del XSLT FAQ.

+0

Te doy un Dolment por señalar la información para mí. En realidad, ya leí un poco de XSLT, pero no lo encontré. Supongo que las preguntas frecuentes son un poco demasiada información para mí. –

+0

Una buena manera de agradecer una respuesta es votar por ella haciendo clic en la flecha hacia arriba en el lado izquierdo. ¿Podrías hacerlo por el mío? – dolmen

+0

Votado para las preguntas frecuentes XLT. – Fortisimo

Cuestiones relacionadas