2011-08-24 9 views
6

Tengo la siguiente parte del archivo xml.¿Cómo recuperar el último nodo usando XPath en C#?

<UN N="@U1"> 
    <DT N="24/06/2011"> 
     <PN N="@P1"> 
      <TM N="02:24:11"> 
       <JB T="GP"> 
        <A>notepad</A> 
        <Z>Notepad</Z> 
        <N>Untitled - Notepad</N> 
        <J>1;0;1;1;0;0</J> 
        <C>0.00500;0.09500;0.03500</C> 
        <S>1;0;1;1</S> 
        <P>0;0</P> 
        <F>0</F> 
       </JB> 
      </TM> 
     </PN> 
    </DT> 

    <DT N="23/06/2011"> 
     <PN N="@P1"> 
      <TM N="02:38:49"> 
       <JB T="PAGP"> 
        <A>notepad</A> 
        <Z>Notepad</Z> 
        <N>Untitled - Notepad</N> 
        <J>1;1;1;1;0;1</J> 
        <C>0.00500;0.09500;0.03500</C> 
        <S>1;1;0;0</S> 
        <P>1;1</P> 
        <F>0</F> 
       </JB> 
      </TM>    
     </PN> 
    </DT> 

    ..... 
    ..... 

</UN> 

Necesito obtener el último nodo donde PN N = @ P1.

La consulta de la muestra será apreciada.

Gracias de antemano.

+0

¿Está buscando un nodo '

' o '' que se puede encontrar? – Richard

Respuesta

5

La función XPath last() se puede utilizar para encontrar el último de un conjunto de nodos. Así que la última <PN> nodo con attribyte N tener un valor @P1 sería:

//PN[@N='@P1'][position() = last()] 

El código .NET dependerá de qué API XML que está utilizando: XmlDocument, XPathDocument o LINQ to XML (XDocument). (El enfoque con XmlReader sería cargar en uno de los tres y luego usar esa.)

Editar (basado en comentario) Para devolver el <F> descendiente de la última <PN> con el atributo que el anterior, donde xDoc es una instancia de XmlDocument:

var foundNode = xDoc.SelectSingleNode("//PN[@N='@P1'][position() = last()]/TM/JB/F"); 

Edición # 2 (basado en otro comentario): Para regresar la última <PN> donde cada uno puede contener múltiples <DT><DT> elementos en todos los elementos <DT>.

Probando esto con un ejemplo de XML mejor (ver más abajo), usando XmlElement.SelectNodes y luego iterando sobre el conjunto de nodos devuelto mostró que se encontró el nodo derecho, simplemente no fue el primero y por lo tanto no devuelto por SelectSingleNode. Esta es la clave: el predicado last() se estaba aplicando dentro de cada coincidencia //PN[@N='@P1']. Un cambio rápido de precedencia era todo lo que se necesitaba:

(//PN[@N='@P1'])[last()] 

Para referencia futura, si son posibles múltiples elementos, a continuación, mostrar al menos dos en la muestra, de lo contrario los lectores asumirán casos solamente singulares . También tira a todos los nodos (como los niños) que no son necesarios:

El XML de ejemplo he utilizado para las pruebas (añadido x atributos para que sea fácil de identificar el elemento seleccionado durante la prueba):

<UN N='@U1'> 
    <DT N='24/06/2011'> 
    <PN N='@P1' x='#1'/> 
    <PN N='@P1' x='#2'/> 
    <PN N='@P2' x='#3'/> 
    </DT> 

    <DT N='24/06/2011'> 
    <PN N='@P1' x='#4'/> 
    <PN N='@P1' x='#5'/> 
    <PN N='@P2' x='#6'/> 
    </DT> 

    <DT N='24/06/2011'> 
    <PN N='@P3' x='#7'/> 
    <PN N='@P4' x='#8'/> 
    <PN N='@P5' x='#9'/> 
    </DT> 
</UN> 
+0

Gracias, está funcionando magníficamente. ¿Qué pasa si quiero recuperar el último nodo de TM/JB/F del nodo devuelto? Estoy usando la clase XmlDocument. – Syed

+0

Me encontré a mí mismo.será así: '@ "// PN [@N =' @ P1 '] [posición() = último()]/TM [posición() = último()]/JB/F";' De todos modos, gracias por la inicial XPath. – Syed

+0

Lo sentimos tarde para comentar. Devuelve el último nodo PN de DT, pero necesito el último nodo, independientemente de DT en el archivo .xml. Nota: el archivo .xml puede contener cualquier cantidad de DT y dentro de DT contiene muchos números de PN. – Syed

6

La operación XPath:

"/UN/DT[PN/@N='@p1'][last()]" 

devolverá el último nodo DT para los que [email protected].

Cuestiones relacionadas