2009-02-17 13 views
15
<Document> 
    <A> 
    <B> 
     <C></C> 
    </B> 
    </A> 
    <E> 
    <F> 
    <C></C> 
    </F> 
    <G> 
    <C></C> 
    </G> 
</E> 
</Document> 

Si se me carga el XML anterior en un XmlDocument y hacer un SelectSingleNode en A mediante la consulta XPath // CSelectNodes XPath en .NET

 
XmlNode oNode = oDocument.SelectSingleNode("E"); 
XmlNodeList oNodeList = oNode.SelectNodes("//C"); 

¿por qué volver linfáticos que están debajo B cuando lo Esperaría que sucediera que solo devolvería nodos desde menos de

¿Tiene sentido?

Editar: ¿Cómo haré que solo regrese desde ese nodo en adelante?

Respuesta

22

Simplemente: un líder // significa "en cualquier nivel" en el mismo documento como el nodo seleccionado.

Desde el spec:

  • // para selecciona todos los descendientes para de la raíz del documento y por lo tanto selecciona todos los elementos para en el mismo documento que el nodo de contexto
  • .//para selecciona el párrafo Elemento descendientes del nodo de contexto
11

Al especificar .//C obtendrá lo que desee; de ​​lo contrario, la XPath se iniciará desde la raíz del documento en lugar del nodo actual.

La confusión es en la definición de // de la XPath standard como sigue:

// es la abreviatura de /descendiente-o-self :: node() /. Para ejemplo, // para es la abreviatura de /descenddant-o-self :: node()/child :: para y así seleccionará cualquier elemento para en el documento (incluso un elemento para que es un elemento de documento se seleccionará por // para ya que el nodo del elemento de documento es hijo del nodo raíz); div // para es la abreviatura de div/descendiente-o-uno mismo :: node()/child :: para y así seleccionará todos los descendientes para de div children.

Debido // es la abreviatura de /descendant-or-self::node()/ que se inicia en el nivel de documento a menos que especifique un nodo en la salida.

+0

No, la especificación dice "//" es "de la raíz del documento", y ".//" es del nodo de contexto. La implementación es correcta. –

+0

Re las escuelas W3 ref: lea atentamente: "en el documento del nodo actual" - el nodo de contexto se usa (solamente) para obtener el documento; luego se escanea todo el documento. –

+0

Sí, lo actualicé para hacer referencia al estándar XPath y resaltar dónde se encuentra la confusión. Gracias. :) –

6

//C es que todos los nodos C en todo el documento

/E//C habría sólo los nodos C bajo E

/C habría sólo el nodo raíz C

Ver el xpath syntax reference

3

En el XPATH Specification encontrará debajo de 2.5 la siguiente declaración:

// para selecciona todos los para descendientes de la raíz del documento y por lo tanto selecciona todos los elementos para en el mismo documento como el nodo de contexto

es decir, el comportamiento que observar es válido. Debería hacer algo como "/ E // C"

+0

¿Qué pasaría si no supiera cuántos nodos tenía C profunda? Bien podría ser/E/D/G/C? –

+0

@Gordon - "/ E // C" hará frente a cualquier cantidad de niveles entre el E y el C. –