Compilazione, selezione, valutazione e corrispondenze con XPath e XPathExpressions
Un oggetto XPathExpresion rappresenta un'espressione XPath restituita dal metodo Compile. Questo metodo è utile se si utilizza la stessa query più di una volta. Se l'espressione fornita al metodo Compile non è valida, verrà generata un'eccezione. L'unico caso in cui ciò non viene generata un'eccezione per un'espressione non valida, è quando XPathExpression è una funzione definita dall'utente. In questo caso, viene generata un'eccezione in fase di esecuzione, quando l'espressione viene valutata e ritenuta errata.
Se un metodo Select viene richiamato ripetutamente, invece di utilizzare il valore di una stringa a ogni occasione, utilizzare il metodo Compile per compilare e memorizzare nella cache l'oggetto XpathExpression per riutilizzarlo, migliorando così le prestazioni.
Dim xpeCache As Object = Nothing
xpeCache = nav.Compile("//book[@author="smith"//BookPrice[.>50]")
nav.Select(xpeCache)
[C#]
object xpeCache = null;
xpeCache = nav.Compile("//book[@author="smith"//BookPrice[.>50]");
nav.Select(xpeCache);
Una volta compilata, è possibile utilizzare la XPathExpression come input per i metodi Select, Evaluate e Matches, a seconda del tipo restituito da un'espressione XPath o dell'espressione XPath compilata. Nella tabella che segue sono riportati il tipo di espressione restituito, una descrizione e i metodi in cui l'espressione può essere utilizzata.
Tipo W3C XPath restituito | Classe .NET equivalente (tipo) | Descrizione | Metodi nei quali viene utilizzato |
---|---|---|---|
node set | System.Xml.XPath.XPathNodeIterator | Insieme di nodi non ordinati, senza duplicati creati in ordine di documento. | Select o Evaluate |
Boolean | System.Boolean | Un valore True o False. | Evaluate |
number | System.Double | Numero a virgola mobile. | Evaluate |
string | System.String | Sequenza di caratteri UCS. | Evaluate |
Il metodo Matches utilizza i criteri XSLT come argomento.
Se si compila una query XPath ed è necessario sapere che cosa restituisce, è possibile utilizzare la proprietà ReturnType. Nella tabella che segue, è riportata l'enumerazione XPathResultType restituita e una descrizione del tipo di espressione XPath rappresentata dall'enumerazione.
Enumerazione XPathResultType | Descrizione dei tipi XPath W3C |
---|---|
0 | String |
1 | Boolean |
2 | Number |
3 | Node set |
5 | Qualsiasi |
Nell'esempio di codice seguente viene illustrato come l'enumerazione dei tipo restituito può essere utilizzata per verificare correttamente il tipo restituito di un'espressione XPath o una XPathExpression compilata.
Dim doc As New XPathDocument("books.xml")
Dim nav As XPathNavigator = doc.CreateNavigator()
' The following line returns a number.
Dim Expr As XPathExpression = nav.Compile("/Price/text()*10")
' The following line returns a node set.
Dim Expr2 As XPathExpression = nav.Compile("books/book/price")
Select Case Expr.NodeType
Case XPathResultType.Number
nav.Evaluate(Expr)
Case XPathResultType.Nodeset
Dim iterator as XPathNodeIterator
iterator = nav.Select(Expr)
If iterator.MoveNext() Then
End If
Case XPathResultType.Boolean
nav.Evaluate(Expr)
Case XPathResultType.String
nav.Evaluate(Expr)
Case Else
Throw New Exception("Invalid XpathResultType")
End Select
[C#]
XPathDocument doc = new XPathDocument("books.xml");
XPathNavigator nav = doc.CreateNavigator();
// The following line returns a number.
XPathExpression Expr = nav.Compile("/Price/text()*10");
// The following line returns a node set.
XPathExpression Expr2 = nav.Compile("books/book/price");
switch(Expr.ReturnType)
{
case XPathResultType.Number:
nav.Evaluate(Expr);
break;
case XPathResultType.Nodeset:
XPathNodeIterator iterator = nav.Select(Expr);
if (iterator.MoveNext()) {}
break;
case XPathResultType.Boolean:
nav.Evaluate(Expr);
break;
case XPathResultType.String:
nav.Evaluate(Expr);
break;
case default:
throw new Exception("Invalid XPathResultType");
break;
}
Quando si crea un'istanza di XPathDocument, è possibile utilizzare vari oggetti per fornire l'XML di origine, inclusi una stringa, un flusso, TextReader e XmlReader. Quando per fornire l'XML di origine si utilizza un XmlReader, se il reader è posizionato su un nodo, i dati vengono caricati dalla posizione corrente del reader attraverso tutti i nodi di pari livello. In questo modo è possibile caricare solo una parte del documento. Se il reader è posizionato su un nodo secondario non valido come primo livello del documento, ad esempio un carattere spazio o un tipo di nodo di attributo, il reader proseguirà la lettura fino a quando verrà posizionato su un nodo che potrà essere utilizzato come primo livello. Il caricamento del documento avverrà a partire da questo punto.
Per ottimizzare le prestazioni, si consiglia di utilizzare l'espressione più specifica possibile. Se il nodo book
si trova sotto il nodo bookstore
e il nodo bookstore
è l'elemento di primo livello, utilizzando /bookstore/book
si ottengono prestazioni migliori che con //book
, poiché nel secondo caso vengono esaminati tutti i nodi della gerarchia di dati XML per identificare i nodi corrispondenti. Inoltre, l'utilizzo di Select per ottenere migliori prestazioni dipende dallo scenario. Se però la selezione è così semplice che pochi metodi di spostamento sono sufficienti per restituire i dati e non vi è bisogno di tenere traccia delle informazioni di stato, i metodi Move potrebbero essere più rapidi di Select. Se, ad esempio, è necessario il primo figlio del nodo corrente, sarà più rapido utilizzare MoveToFirst anziché eseguire una chiamata Select("child::*[1]").
Per ulteriori informazioni su come selezionare ed eseguire un'iterazione sui nodi di un archivio dati, vedere Select con XPath e XPathNavigator.
Per ulteriori informazioni su come valutare un'espressione in un nodo, vedere Evaluate con XPath e XPathNavigator.
Per ulteriori informazioni su come verificare se il nodo corrente corrisponde a un'espressione XPath, vedere Matches con XPath e XPathNavigator.