2009-05-19 11 views
13

Mi XML se parece a:El uso de XPath en SelectSingleNode: Recuperando elemento individual a partir de XML si está presente

<?xml version=\"1.0\"?> 
<itemSet> 
     <Item>one</Item> 
     <Item>two</Item> 
     <Item>three</Item> 
     .....maybe more Items here. 
</itemSet> 

Algunos de los individuos artículo puede o no estar presente. Supongamos que quiero recuperar el elemento <Item>dos</Item> si está presente. He intentado los siguientes XPaths (en C#).

  • XMLNode node = myXMLdoc.SelectSingleNode("/itemSet[Item='two']") --- Si el artículo dos está presente, entonces me devuelve sólo el primer elemento de una . Tal vez esta consulta simplemente apunta al primer elemento en itemSet, si tiene un elemento de valor dos en alguna parte como un niño. ¿Es correcta esta interpretación?

así que he intentado:

  • XMLNode node = myXMLdoc.SelectSingleNode("/itemSet[Item='two']/Item[1]") --- He leído esta consulta como, me devuelve el primer elemento <Item> dentro de conjunto de elementos que tiene valor = 'dos'. ¿Estoy en lo correcto?

Esto todavía devuelve sólo el primer elemento de una . ¿Qué estoy haciendo mal? En ambos casos, usando los hermanos puedo atravesar los nodos secundarios y llegar a dos, pero eso no es lo que estoy mirando. Además, si dos están ausentes, SelectSingleNode devuelve null. Por lo tanto, el hecho de que estoy obteniendo un nodo de retorno exitoso indica la presencia del elemento dos, así que si hubiera deseado una prueba booleana para detectar la presencia de dos, cualquiera de los XPath anteriores sería suficiente, pero de hecho necesito el completo elemento <Item>two</Item> como mi nodo de retorno.

[Mi primera pregunta aquí, y la primera vez que trabajo con programación web, por lo que acabo de aprender los XPath anteriores y material xml relacionado sobre la marcha en este momento de preguntas pasadas en SO. Así que sé gentil y avísame si soy un imbécil o incumpliendo las reglas de la comunidad. . Gracias]

Respuesta

23

creo que quiere:

myXMLdoc.SelectSingleNode("/itemSet/Item[text()='two']") 

En otras palabras, desea que el artículo que tiene el texto de dos, no es el itemSet que lo contiene.

También puede utilizar un solo punto para indicar el nodo de contexto, en su caso:

myXMLdoc.SelectSingleNode("/itemSet/Item[.='two']") 

EDIT: La diferencia entre . y text() es que . significa "este nodo" de manera efectiva, y text() medios " todos los hijos del nodo de texto de este nodo ". En ambos casos, la comparación será contra el "valor de cadena" de LHS. Para un nodo de elemento, el valor de cadena es "la concatenación de los valores de cadena de todos los descendientes de nodo de texto del nodo de elemento en orden de documento" y para una colección de nodos de texto, la comparación comprobará si cualquier nodo de texto es igual a el que estás probando en contra.

por lo que no importa cuando el contenido de elementos sólo tiene un nodo de texto sencillo, pero supongamos que tenemos:

<root> 
    <item name="first">x<foo/>y</item> 
    <item name="second">xy<foo/>ab</item> 
</root> 

Entonces una expresión XPath de "root/item[.='xy']" coincidirá con el primer elemento, pero "root/item[text()='xy'] "coincidirá con el segundo.

+0

Gracias a ton Jon. Ambas soluciones funcionaron como un encanto. Mientras estoy en el tema, ¿puedo preguntar cuál es la diferencia entre usar texto() y.? En mi XML de muestra, es un elemento simple con solo un valor de texto, por lo que ambas soluciones devuelven lo mismo. ¿Existe una situación XML complicada en la que uno es preferido sobre el otro o los resultados son diferentes? (Además de marcar el año antes de corregir y votar, ¿hay algo TAN comunal que pueda hacer para agradecerle?) –

+0

@areaMan: Para ser sincero, no estoy seguro de la diferencia entre "texto()" y " . ". Mi XPath-fu es bastante mínimo :) Es posible que desee consultar las especificaciones de XPath para obtener más información: http://www.w3.org/TR/xpath En cuanto a lo que puede hacer para agradecerme ... encuentra una pregunta que puedas responder y respóndela lo mejor que puedas. Ah, y sigue haciendo buenas preguntas :) –

+0

Habiendo dicho eso acerca de no saber la diferencia, sé * algunas * de las diferencias entre. y text() - editará. –

Cuestiones relacionadas