2008-08-25 12 views
11

estoy usando XPath en .NET para analizar un documento XML, a lo largo de las líneas de:XPath y selección de un solo nodo

XmlNodeList lotsOStuff = doc.SelectNodes("//stuff"); 

foreach (XmlNode stuff in lotsOStuff) { 
    XmlNode stuffChild = stuff.SelectSingleNode("//stuffChild"); 
    // ... etc 
} 

La cuestión es que la consulta XPath para stuffChild siempre está regresando al niño de el primer elemento stuff, nunca el resto. ¿Puede XPath no usarse para consultar contra un individuo XMLElement?

Respuesta

10

// al comienzo de una expresión XPath se inicia desde la raíz del documento. Prueba ".//stuffChild". . es una abreviatura de self :: node(), que establecerá el contexto para la búsqueda, y // es una abreviación para el eje descendiente.

Por lo que tiene:

XmlNode stuffChild = stuff.SelectSingleNode(".//stuffChild"); 

que se traduce en:

XmlNode stuffChild = stuff.SelectSingleNode ("self :: node()/descendiente :: stuffChild");

xmlNode stuffChild = stuff.SelectSingleNode("self::node()/descendant-or-self::stuffChild"); 

En el caso de que el nodo hijo podría tener el mismo nombre que el padre, usted querría usar la sintaxis un poco más detallado que sigue, para asegurar que no vuelva a seleccionar el padre:

xmlNode stuffChild = stuff.SelectSingleNode("self::node()/descendant::stuffChild"); 

también tenga en cuenta que si "stuffChild" es un descendiente directo de "cosas", se puede omitir por completo los prefijos, y sólo tiene que seleccionar "stuffChild".

XmlNode stuffChild = stuff.SelectSingleNode("stuffChild"); 

El W3Schools tutorial tiene información útil en un formato fácil de digerir.

+0

.//foo es ** no ** igual a descendiente :: foo y en general es una forma ** incorrecta ** de seleccionar nodos descendientes. Consulte http://stackoverflow.com/questions/453191/ –

+0

Quizás se haya perdido el., Que establece el contexto del siguiente XPath. –

+0

Consulte la documentación para la // abreviación. .//foo se traduce a self :: node()/descenddant-or-self :: node()/child :: stuffChild –

2

El // que utiliza delante de stuffChild significa que está buscando stuffChild elementos, comenzando desde la raíz.

Si desea iniciar desde el nodo actual (descendientes del nodo actual), se debe utilizar .//, como en:

stuff.SelectSingleNode(".//stuffChild"); 
1

Si "stuffChild" es un nodo secundario de "cosas", a continuación, su xpath solo debe ser:

XmlNode stuffChild = stuff.SelectSingleNode("stuffChild"); 
-1

Seleccionar un solo nodo significa que solo necesita el primer elemento. Entonces, la mejor solución es:

XmlNode stuffChild = stuff.SelectSingleNode("descendant::stuffChild[1]"); 
Cuestiones relacionadas