Evaluate con XPath e XPathNavigator

Le espressioni XPath quali una stringa o un'espressione XPathExpression compilata che restituisce un tipo XPath W3C boolean (System.Boolean), number (System.Double), string (System.String) o node set (System.Xml.XPath.XPathNodeIterator), possono essere passate al metodo Evaluate. L'espressione viene presa dal metodo Evaluate che la valuta e la restituisce come risultato tipizzato. È possibile utilizzare questo metodo in un metodo matematico definito dall'utente. Nel codice seguente, ad esempio, viene calcolato il prezzo totale di tutti gli elementi item che si trovano all'interno di un elemento order nella selezione corrente.

Dim doc as XmlDocument = new XmlDocument()
doc.Load("order.xml")
Dim nav as XPathNavigator = doc.CreateNavigator()

' Calculate the total of the order.
Dim expr as XPathExpression = nav.Compile("sum(//price/text())")
Dim total as double = CType(nav.Evaluate(expr), double)
[C#]
XmlDocument doc = new XmlDocument();
doc.Load("order.xml");
XPathNavigator nav = doc.CreateNavigator();

// Calculate the total of the order.
XPathExpression expr = nav.Compile("sum(//price/text())");
double total = (double) nav.Evaluate(expr);

Funzioni position e last del metodo Evaluate

Evaluate è un metodo di overloading. La firma Evaluate public virtual object Evaluate(XPathExpression xpathexpr, XPathIterator nodeset); fornisce un argomento di input XPathNodeIterator per XPathIterator. Questo particolare metodo Evaluate è identico al metodo Evaluate(string xpathexpr), ma consente di utilizzare un argomento di tipo node set per fornire il contesto corrente sul quale eseguire la valutazione. Questa operazione è necessaria per le funzioni last e position di XPath in quanto esse sono relative al nodo di contesto corrente.

Salvo nel caso in cui vengano utilizzate come predicato in un'operazione relativa alla posizione, per la valutazione delle funzioni XPath position e last, è necessario un riferimento a un gruppo di nodi. In questo caso, è necessario utilizzare il metodo di overloading che accetta XPathNodeIterator come argomento; in caso contrario, position e last restituiranno 0.

Inoltre, poiché la funzione XPath restituisce il valore della posizione del contesto e la funzione position viene valutata in relazione al nodo corrente in un gruppo di nodi selezionato, è necessario che almeno un nodo sia stato selezionato con il metodo Select. In breve, la query passata attraverso i metodi Select ed Evaluate viene utilizzata come contesto. Poiché la funzione position riguarda solamente il nodo corrente, se quest'ultimo non si trova nel gruppo dei nodi selezionati, ad esempio se viene chiamato il metodo MoveToNext per passare a un nodo che non appartiene all'insieme dei nodi selezionati, viene generata un'eccezione. Nell'esempio che segue, l'XSLT crea un numero in base alla posizione del nodo.

<xsl:number value='position()'>

La funzione last di XPath utilizza inoltre XPathNodeIterator come contesto e restituisce il numero totale dei nodi selezionati con i metodi Select o Evaluate. Se non risulta selezionato alcun nodo, verrà restituito 0.

L'XML illustrato di seguito è chiamato numbers.xml e costituisce l'input del seguente codice di esempio:

Input

<mydoc>
<numbers>
         <n>1</n> 
      <n>2</n> 
          <n>3</n> 
     </numbers>
     <numbers>
          <n>1</n> 
          <n>1</n> 
          <n>2</n> 
          <n>2</n> 
          <n>3</n> 
          <n>4</n> 
     </numbers>
     <numbers>
          <n>5</n> 
          <n>NaN</n> 
          <n>0</n> 
     </numbers>
</mydoc>

Nell'esempio di codice seguente viene utilizzato il metodo Evaluate con la funzione position, che restituisce la posizione 0.

Dim strXmlFile As [String] = "numbers.xml"
Try
    Dim oXDoc As New XPathDocument(strXmlFile)
    ' Define the context node expression.
    Dim temp As String = "//n"
    Dim oDNav As XPathNavigator = oXDoc.CreateNavigator()
    Dim expr As XPathExpression = oDNav.Compile(temp)
    Dim oIterator As XPathNodeIterator = oDNav.Select(expr)
    ' Move to context.
    If Not oIterator.MoveNext() Then
        Console.WriteLine("Could not move to context node")
        Return
    End If
    Console.WriteLine(oIterator.Current.Evaluate("position()"))

    Catch ex As Exception
        Console.WriteLine(ex)
        Return False
End Try
Return True
[C#]
String strXmlFile = "numbers.xml";
   try 
   {
          XPathDocument oXDoc = new XPathDocument(strXmlFile);
      // Define the context node expression.
      string temp = "//n";
      XPathNavigator oDNav= oXDoc.CreateNavigator();
      XPathExpression expr = oDNav.Compile(temp);
      XPathNodeIterator oIterator = oDNav.Select(expr);
      // Move to context.
      if(!oIterator.MoveNext())
      {
      Console.WriteLine("Could not move to context node");
         return;
      }
         Console.WriteLine(oIterator.Current.Evaluate("position()"));
    }

    catch(Exception ex)     
    {
          Console.WriteLine(ex);
          return false;
    }
    return true;

Vedere anche

XPathNavigator in .NET Framework | Select con XPath e XPathNavigator | Matches con XPath e XPathNavigator