2011-02-01 17 views
17

Estoy escribiendo una transformación XSL. Quiero escribir una plantilla que coincida con todos los elementos secundarios del documento, excepto un nodo en particular. Mi XML se parece a esto -Cómo escribir un xpath para hacer coincidir todos los elementos excepto un elemento en particular

<Document> 
    <NodeA></NodeA> 

    <NodeB></NodeB> 

    <ServiceNode></ServiceNode> 

    <NodeX></NodeX> 
</Document> 

Quiero escribir una plantilla que coincida con todos los nodos excepto ServiceNode decir NodeA a NodeX. Cómo escribir este XPath para conseguir -

<xsl:template match="ALL Nodex Except ServiceNode"> 
+0

Buena pregunta, 1. Vea mi respuesta para cuatro soluciones alternativas para cuatro posibles significados diferentes de esta pregunta. –

Respuesta

26

Quiero escribir una plantilla que los partidos todos los nodos excepto ServiceNode decir NodoA a nodeX.

Si por "nodo" quiere decir elemento, a continuación, utilizar:

<xsl:template match="*[not(self::ServiceNode)]"> 

Si por "nodo" se refiere a cualquier nodo (del elemento de tipo, texto, comentario, instrucción de procesamiento) : utilizar

<xsl:template match="node()[not(self::ServiceNode)]"> 

Si desea que sólo los hijos de Document ser emparejado uso:

<xsl:template match="Document/node()[not(self::ServiceNode)]"> 

Si desea uso exclusivo hijos del elemento superior, que se ajustará:

<xsl:template match="/*/node()[not(self::ServiceNode)]"> 
2
<xsl:template match="Document/*[name() != 'ServiceNode']"> 

(o local-name() si tiene que lidiar con los espacios de nombres)

+0

Recomiendo probar en un evaluador en vivo como http://www.whitebeam.org/library/guide/TechNotes/xpathtestbed.rhtm donde puede pegar expresiones como // * [name()! = "Pet"] –

+0

Very error propenso ... –

0
/Document/*[not(name()='ServiceNode')] 
4

qué debería utilizar mejor esta expresión:

*[not(self::ServiceNode)] 

Según lo incorporado en un XSLT:

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

    <xsl:template match="/*"> 
     <xsl:apply-templates select="*[not(self::ServiceNode)]"/> 
    </xsl:template> 

    <xsl:template match="*"> 
     <xsl:value-of select="."/> 
     <xsl:text>&#xA;</xsl:text> 
    </xsl:template> 

</xsl:stylesheet> 

Con esta muestra XML:

<Document> 
    <NodeA>1</NodeA> 
    <NodeB>2</NodeB> 
    <ServiceNode>3</ServiceNode> 
    <NodeX>4</NodeX> 
</Document> 

que dará un resultado correcto:

1 
2 
4 
+4

Correcto. Esto es mejor que probar en name() o local-name(). En XPath 2.0 una alternativa es (* excepto ServiceNode) –

+0

Acepto. Mejor que 'nombre()'. –

+0

@Alejandro, no olvide votar, si lo consideró;) – Flack

1

se pueden utilizar dos plantillas:

<xsl:template match="Document/*"> 
    ...do something... 
</xsl:template> 


<xsl:template match="Document/ServiceNode" /> 

La plantilla más adelante tendrá prioridad, por lo que la primera plantilla coincidirá con todo, excepto ServiceNode.

+0

Esto podría ser útil en algunos casos, además de que no responde esta pregunta correctamente. –

Cuestiones relacionadas