2011-08-24 21 views
6

Mam następującą część pliku xml.Jak pobrać ostatni węzeł przy użyciu XPath w języku 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> 

Potrzebuję uzyskać ostatni węzeł, w którym PN N = @ P1.

Przykładowe zapytanie zostanie docenione.

Z góry dziękuję.

+0

szukasz znaleziono '

' lub '' węzeł? – Richard

Odpowiedz

5

Funkcja XPath last() może być użyta do znalezienia ostatniego zestawu węzłów. Więc ostatni <PN> węzeł z attribyte N o wartości @P1 byłoby:

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

Kod .NET będzie zależeć od którego XML API używasz: XmlDocument, XPathDocument lub LINQ to XML (XDocument). (Metoda z XmlReader byłoby załadować do jednego z trzech, a następnie użyć.)

Edit (oparte na komentarzu) Aby przywrócić <F> potomek ostatniego <PN> z atrybutu jak wyżej, gdzie xDoc jest instancja XmlDocument:

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

Edit # 2 (oparte na innym komentarzu): Aby przywrócić ostatni<PN> gdzie każdy <DT> może zawierać wiele <DT> elementy na wszystkie elementy <DT>.

Testowanie to z jakiegoś lepszego próbki XML (patrz poniżej), a następnie za pomocą XmlElement.SelectNodes Iteracja nad zwróconego zestawu węzłów wykazała, że ​​prawy węzeł był znaleziony, to po prostu nie był pierwszy i dlatego nie wrócił przez SelectSingleNode. Oto wskazówka: w każdym dopasowaniu last() zastosowano dopasowanie. Szybka zmiana pierwszeństwa było wszystko, co było potrzebne:

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

Na przyszłość, jeśli wiele elementów są możliwe, a następnie pokazać co najmniej dwie próby, w przeciwnym razie czytelnicy będą zakładać tylko w liczbie pojedynczej instancji . Również rozebrać wszystkie węzły (jak dzieci) nie potrzebne:

Próbka XML użyłem do testów (dodane x atrybuty sprawiają, że łatwo zidentyfikować element wybrany podczas testów):

<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

Dzięki, działa znakomicie. Co jeśli chcę odzyskać ostatni węzeł TM/JB/F z zwróconego węzła. Używam klasy XmlDocument. – Syed

+0

Znalazłem siebie.będzie to tak: "@" // PN [@N = '@ P1'] [position() = last()]/TM [position() = last()]/JB/F "; Wszelkie podziękowania za początkowy XPath. – Syed

+0

Przepraszamy za opóźnienie. Zwraca pierwszy węzeł PN ostatniego ID, ale potrzebuję ostatniego węzła niezależnie od ID w pliku .xml. Uwaga: plik .xml może zawierać dowolną liczbę DT i wewnątrz DT, które zawierają wiele numerów PN. – Syed

6

Operacja XPath:

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

zwróci ostatnią DT węzeł dla którego [email protected].

Powiązane problemy