Tipp-Upload: VB.NET 0149: XPath-Ausdrücke verwenden
von Spatzenkanonier
Hinweis zum Tippvorschlag
Dieser Vorschlag wurde noch nicht auf Sinn und Inhalt überprüft und die Zip-Datei wurde noch nicht auf schädlichen Inhalt hin untersucht.
Bitte haben Sie ein wenig Geduld, bis die Freigabe erfolgt.
Über den Tipp
Dieser Tippvorschlag ist noch unbewertet.
Der Vorschlag ist in den folgenden Kategorien zu finden:
- Datenbanken und XML
- Sonstiges
Dem Tippvorschlag wurden folgende Schlüsselwörter zugeordnet:
XPath,xml
Der Vorschlag wurde erstellt am: 22.11.2007 18:34.
Die letzte Aktualisierung erfolgte am 27.01.2009 18:26.
Beschreibung
Hier 8 Beispiele, wie man mit XPath-Ausdrücken einer Xml-Datei nahezu jede Information entreißen kann - und zwar jeweils mit einem 3-Zeiler.
Untersucht wird einfach die Kopie der ProjektDatei dieses Projektes.
Die ausgeführten Abfragen lassen sich sicherlich wesentlich optimieren, etwa durch Verwendung von XPathDocument und XPathIterator.
Der Tipp soll nur Appetit machen auf eine systematischere Auseinandersetzung mit der Abfragesprache "XPath"
MSDN fand ich wenig hilfreich, aber die W3Schools:
http://www.w3schools.com/xpath/default.asp
Hier kann dieser Tippvorschlag diskutiert werden:
http://foren.activevb.de/cgi-bin/foren/view.pl?forum=13&root=1471&msg=1471
Schwierigkeitsgrad |
Verwendete API-Aufrufe: |
Download: |
' Dieser Source stammt von http://www.activevb.de ' und kann frei verwendet werden. Für eventuelle Schäden ' wird nicht gehaftet. ' Um Fehler oder Fragen zu klären, nutzen Sie bitte unser Forum. ' Ansonsten viel Spaß und Erfolg mit diesem Source! ' ' Beachten Sie, das vom Designer generierter Code hier ausgeblendet wird. ' In den Zip-Dateien ist er jedoch zu finden. ' ----------- Anfang Projektgruppe XPathSample.sln ----------- ' ---------- Anfang Projektdatei XPathSample.vbproj ---------- ' -------------- Anfang Datei frmXPathSample.vb -------------- ' IDE-Voreinstellungen: ' Option Explicit On ' Option Strict On ' Project-Einstellungen: ' Imports Microsoft.VisualBasic.ControlChars ' Imports System.Windows.Forms Imports System.Xml Imports System.IO Public Class frmXPathSample Private Enum QueryEnum CompileElement = 1 CompileIncludeAttribute CompileIncludeAttribute2 DefaultProperties AssemblyName OptionStrict UpdateStuff EckardsSpecial End Enum Private _XDoc As New XmlDocument Public Sub New() InitializeComponent() ' auch vllt. interessant: Listbox dynamisch mit Enums befüllen. ' So ist sie immer genau auf die im Code verwendbaren Optionen abgestimmt Me.ListBox1.DataSource = [Enum].GetValues(GetType(QueryEnum)) _XDoc.Load(Path.Combine(Application.StartupPath, "XPathSample.vbproj")) End Sub Private Sub btQuery_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btQuery.Click Dim NspMngr As New XmlNamespaceManager(_XDoc.NameTable) ' Falls ein Default-Namespace vorhanden: denselben dem XmlNamespaceManager bekanntmachen, ' unter beliebigem Präfix NspMngr.AddNamespace("def", _XDoc.DocumentElement.NamespaceURI) Dim SB As New System.Text.StringBuilder Dim sXPath As String = "" Dim QueryType As QueryEnum = DirectCast(Me.ListBox1.SelectedItem, QueryEnum) Select Case QueryType Case QueryEnum.CompileElement ' Für XmlElemente ist ggfs. der Namespace anzugeben (hier: Default) sXPath = "def:Project/def:ItemGroup/def:Compile" Dim Nodes As XmlNodeList = _XDoc.SelectNodes(sXPath, NspMngr) For Each Xel As XmlElement In Nodes SB.Append(Xel.OuterXml & Lf & Lf) Next Case QueryEnum.CompileIncludeAttribute ' "//" ist eine Art Wildcard für alle Ebenen - returnt dieselbe Nodelist wie vorher For Each Xel As XmlElement In _XDoc.SelectNodes("//def:Compile", NspMngr) ' Ausgabe: greift den "Include"-Attribut-Wert heraus (also die Namen zu ' kompilierender Dateien) SB.Append(Xel.GetAttribute("Include") & Lf) Next ' -------- Ausgabe: --------- ' frmXPathSample.vb ' frmXPathSample.Designer.vb ' My Project\AssemblyInfo.vb ' My Project\Application.Designer.vb ' My Project\Resources.Designer.vb ' My Project\Settings.Designer.vb Case QueryEnum.CompileIncludeAttribute2 ' Diese Query returnt gleich nur die Attribute-Nodes sXPath = "//def:Compile/@Include" For Each XAttr As XmlAttribute In _XDoc.SelectNodes(sXPath, NspMngr) SB.Append(XAttr.Value & Lf) Next Case QueryEnum.DefaultProperties ' anspruchsvollere XPath-Abfrage: ' alle XmlElemente einer PropertyGroup, die kein Condition-Attribut hat sXPath = "//def:PropertyGroup[not(@Condition)]/*" For Each Xel As XmlElement In _XDoc.SelectNodes(sXPath, NspMngr) ' kultivierte Darstellung: Nodename + Innertext SB.Append(String.Concat(Xel.Name, Tab, ": ", Xel.InnerText, Lf)) Next Case QueryEnum.AssemblyName sXPath = "//def:PropertyGroup[not(@Condition)]/def:AssemblyName/text()" ' DirectCast zeigt, daß ein XmlText returnt Dim Nd As XmlText = DirectCast(_XDoc.SelectSingleNode(sXPath, NspMngr), XmlText) SB.Append(Nd.OuterXml) Case QueryEnum.OptionStrict sXPath = "//def:PropertyGroup[not(@Condition)]/def:OptionStrict" With _XDoc.SelectSingleNode(sXPath, NspMngr) SB.Append(String.Concat(.Name, ": ", .InnerText)) End With Case QueryEnum.UpdateStuff ' anspruchsvollere XPath-Abfrage: ' alle XmlElemente der Default-PropertyGroup, deren Name mit 'Update' anfängt sXPath = "//def:PropertyGroup[not(@Condition)]/*[starts-with(name(),'Update')]" For Each Xel As XmlElement In _XDoc.SelectNodes(sXPath, NspMngr) SB.Append(String.Concat(Xel.Name, Tab, ": ", Xel.InnerText, Lf)) Next Case QueryEnum.EckardsSpecial ' Hier greifen wir mal auf einen anderen als den Default-Namespace zu. ' Der Prefix muß mit dem im XPath verwendeten übereinstimmen (kann abweichen von ' dem im Xml-File definierten). Der uri aber muß mit dem aus der Datei ' übereinstimmen. NspMngr.AddNamespace(prefix:="Spatzenkanonier", uri:="HiHaHiHaHu") ' alle Attribute sXPath = "def:Project/Spatzenkanonier:MyElement/@*" For Each XAttr As XmlAttribute In _XDoc.SelectNodes(sXPath, NspMngr) SB.Append(String.Concat(XAttr.Name, Tab, ": ", XAttr.InnerText, Lf)) Next End Select MsgBox(SB.ToString, Title:=QueryType.ToString) End Sub ' btQuery_Click Private Sub btOpenXDoc_Click(ByVal sender As Object, ByVal e As EventArgs) _ Handles btOpenXDoc.Click ' Der Dateiname steckt im XmlDocument drin, muß aber in Pfad-Syntax überführt werden With New Uri(_XDoc.BaseURI) System.Diagnostics.Process.Start("Notepad", .LocalPath) End With End Sub Private Sub btNamespaces_Click(ByVal sender As Object, ByVal e As EventArgs) _ Handles btNamespaces.Click DisplayNamespaces() End Sub Private Sub DisplayNamespaces() ' Over-coded - üblicherweise genügt es, das DocumentElement zu untersuchen Dim SB As New System.Text.StringBuilder SB.Append(String.Concat(" Prefix", Tab, Tab, "NamespaceUri", Lf, Lf)) For Each Xel As XmlElement In _XDoc.SelectNodes("//*") ' alle(!) Elemente nachgucken For Each Attr As XmlAttribute In Xel.Attributes Dim AttrName As String = Attr.Name If AttrName.StartsWith("xmlns") Then Dim Prefix As String = "(no pref)" If AttrName.Length > 6 Then Prefix = AttrName.Substring(6) SB.Append(String.Concat(Prefix, Tab, ": ", Attr.Value, Lf)) End If Next Next MsgBox(SB.ToString, Title:="DisplayNamespaces") ' Den Default-Namespace erhält man noch einfacher: MsgBox(_XDoc.DocumentElement.NamespaceURI, Title:="Default-Namespace") End Sub End Class ' --------------- Ende Datei frmXPathSample.vb --------------- ' ----------- Ende Projektdatei XPathSample.vbproj ----------- ' ------------ Ende Projektgruppe XPathSample.sln ------------
Diskussion
Diese Funktion ermöglicht es, Fragen, die die Veröffentlichung des Tipps betreffen, zu klären, oder Anregungen und Verbesserungsvorschläge einzubringen. Nach der Veröffentlichung des Tipps werden diese Beiträge nicht weiter verlinkt. Allgemeine Fragen zum Inhalt sollten daher hier nicht geklärt werden.
Um eine Diskussion eröffnen zu können, müssen sie angemeldet sein.