Entwickler-Ecke

IO, XML und Registry - XPathNavigator und XPathExpression.AddSort


syracus - Fr 05.11.10 09:51
Titel: XPathNavigator und XPathExpression.AddSort
Hallo,

ich habe folgendes XML (exemplarisch)


XML-Daten
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
<root>
  <person>
    <name>C</name>
  </person>
  <person>
    <name>A</name>
  </person>
  <person>
    <name>B</name>
  </person>
</root>


Über folgenden Code hole ich mir nach dem Feld <name/> sortiert alle Personen.


C#-Quelltext
1:
2:
3:
4:
XPathNavigator navigator = document.CreateNavigator();
XPathExpression expression = navigator.Compile("/root/person");
expression.AddSort("name", XmlSortOrder.Ascending, XmlCaseOrder.LowerFirst, "", XmlDataType.Text);
XPathNodeIterator iterator = navigator.Select(expression);


Die Vorwärtsiteration liefert die Personen in der Reihenfolge A -> B -> C. Soweit alles korrekt.

Nun muss ich aber während der Iteration allerding immer eine Person vorausschauen


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
foreach(XPathNavigator node in iterator)
{
  if (node.MoveToNext())
  {
    nextNode = node;
    // informationen von nextNode holen...
    node = node.MoveToPrevious();
  }
  // weitere verarbeitung der aktuellen node
}


Mein Problem is nun, daß in Zeile 7 nicht der nächste Knoten laut Sortierung von iterator zurück gegeben wird, sondern der nächste Knoten laut Dokumentstruktur. Steht iterator auf C wird also nicht false für MoveToNext geliefert, sondern der Knoten A.

Aus Sicht von XPathNavigator node ist das sicherlich auch korrekt so, nur leider nicht für die Programmlogik :)

Gibt es hier eine Lösung, möglichst mit System.Xml....-Mitteln, ohne selbst Domain-Objekte aus den Knoten erstellen zu müssen ?

Grüße
syracus


Trashkid2000 - Fr 05.11.10 11:29

Hallo,

was hältst Du davon, anstatt der foreach-Schleife so einen Konstrukt zu machen:


C#-Quelltext
1:
IEnumerable<XPathItem> items = iterator.Cast<XPathItem>();                    
Die Items befinden sich dann sortiert in der Collection und können dann ganz einfach per Index angesprochen werden.

Viel Erfolg, Marko


syracus - Fr 05.11.10 11:59

Hi,

die Idee mit dem iterator.Cast funktioniert. Allerdings benutze ich .Cast<XPathNavigator>.

Vielen Dank dafür


Trashkid2000 - Fr 05.11.10 22:08

Hi,

stimmt, das iterator.Cast<XPathNavigator>() ist eigentlich besser, da der XPathNavigator viel mehr Funktionalität mitbringt. Z.B. auch das Auslesen bzw. ändern von Attributen (wenn denn welche da sind).
Hatte auch bloss mal kurz rumprobiert...

Aber schön, dass es Dir geholfen hat.

LG, Marko