Csharp/C Sharp/XML/XPath

Материал из .Net Framework эксперт
Перейти к: навигация, поиск

Find Elements with an XPath Search

using System;
using System.Xml;
public class XPathSelectNodes {
    private static void Main() {
        // Load the document.
        XmlDocument doc = new XmlDocument();
        doc.Load("books.xml");
        XmlNodeList nodes = doc.SelectNodes("/books/A/B");
            
        foreach (XmlNode node in nodes) {
            Console.WriteLine(node.InnerText);
        }
    }
}
/*
<books>
  <A property="a">
    <B>text</B>
    <C>textg</C>
    <D>99999</D>
  </A>
</books>

*/


Read XML node using the XML path

using System;
using System.Xml;
public class SellItems {
  
  static void Main(string [] args) {
    XmlDocument inventory = new XmlDocument();
    inventory.Load("inventory.xml");
    XmlNodeList elements = inventory.SelectNodes("//inventory/items/item");
    foreach (XmlElement element in elements) {
        string productCode = element.GetAttribute("productCode");
        int quantitySold = Int32.Parse(element.GetAttribute("quantity"));
        Console.WriteLine(quantitySold);
        
        string xPathExpression = "//items/item[@productCode="" + productCode + ""]";
        XmlElement inventoryItem = (XmlElement)inventory.SelectSingleNode(xPathExpression);
    
        int quantity = Int32.Parse(inventoryItem.GetAttribute("quantity"));
        quantity -= quantitySold;
        inventoryItem.SetAttribute("quantity",quantity.ToString());
    }
    inventory.Save("inventory.xml");
  }
}
/*
<inventory>
  <date year="2006" month="8" day="27" />
  <items>
    <item quantity="5" productCode="01" description="PHP"  unitCost="9.95" />
    <item quantity="3" productCode="02" description="Perl" unitCost="4.95" />
  </items>
</inventory>
*/


Select by path

using System;
using System.Collections.Generic;
using System.ruponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Xml.XPath;
public class MainClass {
    public static void Main() {
        XmlDocument doc = new XmlDocument();
        doc.Load("books.xml");
        XPathNavigator nav = doc.CreateNavigator();
        if (nav.CanEdit) {
            XPathNodeIterator iter = nav.Select("/bookstore/book/price");
            while (iter.MoveNext()) {
                iter.Current.InsertAfter("<disc>5</disc>");
            }
        }
        doc.Save("newbooks.xml");
    }
}


XmlQuery Example

using System;
using System.Collections.Generic;
using System.ruponentModel;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
using System.Xml;
class Form1 : Form {
    private XmlDocument mDocument;
    private XmlNode mCurrentNode;
    public Form1() {
        InitializeComponent();
        mDocument = new XmlDocument();
        mDocument.Load("XPathQuery.xml");
        mCurrentNode = mDocument.DocumentElement;
        ClearListBox();
    }
    private void DisplayList(XmlNodeList nodeList) {
        foreach (XmlNode node in nodeList) {
            RecurseXmlDocumentNoSiblings(node, 0);
        }
    }
    private void RecurseXmlDocumentNoSiblings(XmlNode root, int indent) {
        if (root == null)
            return;
        if (root is XmlElement) {
            listBoxResult.Items.Add(root.Name.PadLeft(root.Name.Length + indent));
            if (root.HasChildNodes)
                RecurseXmlDocument(root.FirstChild, indent + 2);
        } else if (root is XmlText) {
            string text = ((XmlText)root).Value;
            listBoxResult.Items.Add(text.PadLeft(text.Length + indent));
        } else if (root is XmlComment) {
            string text = root.Value;
            listBoxResult.Items.Add(text.PadLeft(text.Length + indent));
            if (root.HasChildNodes)
                RecurseXmlDocument(root.FirstChild, indent + 2);
        }
    }
    private void RecurseXmlDocument(XmlNode root, int indent) {
        if (root == null)
            return;
        if (root is XmlElement) {
            listBoxResult.Items.Add(root.Name.PadLeft(root.Name.Length + indent));
            if (root.HasChildNodes)
                RecurseXmlDocument(root.FirstChild, indent + 2);
            if (root.NextSibling != null)
                RecurseXmlDocument(root.NextSibling, indent);
        } else if (root is XmlText) {
            string text = ((XmlText)root).Value;
            listBoxResult.Items.Add(text.PadLeft(text.Length + indent));
        } else if (root is XmlComment) {
            string text = root.Value;
            listBoxResult.Items.Add(text.PadLeft(text.Length + indent));
            if (root.HasChildNodes)
                RecurseXmlDocument(root.FirstChild, indent + 2);
            if (root.NextSibling != null)
                RecurseXmlDocument(root.NextSibling, indent);
        }
    }
    private void ClearListBox() {
        listBoxResult.Items.Clear();
    }
    private void radioButtonSelectRoot_CheckedChanged(object sender, EventArgs e) {
        mCurrentNode = mCurrentNode.SelectSingleNode("//books");
        ClearListBox();
        RecurseXmlDocument(mCurrentNode, 0);
    }
    private void buttonClose_Click(object sender, EventArgs e) {
        Application.Exit();
    }
    private void buttonExecute_Click(object sender, EventArgs e) {
        if (textBoxQuery.Text == "")
            return;
        try {
            XmlNodeList nodeList = mCurrentNode.SelectNodes(textBoxQuery.Text);
            ClearListBox();
            DisplayList(nodeList);
        } catch (System.Exception err) {
            MessageBox.Show(err.Message);
        }
    }
    private void radioButtonSelectAllAuthors_CheckedChanged(object sender, EventArgs e) {
        XmlNodeList nodeList = mCurrentNode.SelectNodes("//book/author");
        ClearListBox();
        DisplayList(nodeList);
    }
    private void radioButtonSelectSpecificAuthor_CheckedChanged(object sender, EventArgs e) {
        XmlNodeList nodeList = mCurrentNode.SelectNodes("//book[author="J"]");
        ClearListBox();
        DisplayList(nodeList);
    }
    private void radioButtonSelectAllBooks_CheckedChanged(object sender, EventArgs e) {
        XmlNodeList nodeList = mCurrentNode.SelectNodes("//book");
        ClearListBox();
        DisplayList(nodeList);
    }
    private void radioButtonSetBookAsCurrent_CheckedChanged(object sender, EventArgs e) {
        mCurrentNode = mCurrentNode.SelectSingleNode("book[title="C#"]");
        ClearListBox();
        RecurseXmlDocumentNoSiblings(mCurrentNode, 0);
    }
    private void radioButtonSetBooksAsCurrent_CheckedChanged(object sender, EventArgs e) {
        mCurrentNode = mCurrentNode.SelectSingleNode("//books");
        ClearListBox();
        RecurseXmlDocumentNoSiblings(mCurrentNode, 0);
    }
    private void radioButtonSelectAllChildren_CheckedChanged(object sender, EventArgs e) {
        XmlNodeList nodeList = mCurrentNode.SelectNodes("*");
        ClearListBox();
        DisplayList(nodeList);
    }
    private void InitializeComponent() {
        this.radioButtonSelectRoot = new System.Windows.Forms.RadioButton();
        this.radioButtonSelectAllChildren = new System.Windows.Forms.RadioButton();
        this.radioButtonSetBooksAsCurrent = new System.Windows.Forms.RadioButton();
        this.radioButtonSetBookAsCurrent = new System.Windows.Forms.RadioButton();
        this.radioButtonSelectAllBooks = new System.Windows.Forms.RadioButton();
        this.radioButtonSelectSpecificAuthor = new System.Windows.Forms.RadioButton();
        this.radioButtonSelectAllAuthors = new System.Windows.Forms.RadioButton();
        this.textBoxQuery = new System.Windows.Forms.TextBox();
        this.buttonExecute = new System.Windows.Forms.Button();
        this.buttonClose = new System.Windows.Forms.Button();
        this.listBoxResult = new System.Windows.Forms.ListBox();
        this.SuspendLayout();
        this.radioButtonSelectRoot.AutoSize = true;
        this.radioButtonSelectRoot.Location = new System.Drawing.Point(13, 234);
        this.radioButtonSelectRoot.Size = new System.Drawing.Size(72, 17);
        this.radioButtonSelectRoot.Text = "Select root";
        this.radioButtonSelectRoot.CheckedChanged += new System.EventHandler(this.radioButtonSelectRoot_CheckedChanged);
        this.radioButtonSelectAllChildren.AutoSize = true;
        this.radioButtonSelectAllChildren.Location = new System.Drawing.Point(163, 282);
        this.radioButtonSelectAllChildren.Size = new System.Drawing.Size(104, 17);
        this.radioButtonSelectAllChildren.Text = "Select all children";
        this.radioButtonSelectAllChildren.CheckedChanged += new System.EventHandler(this.radioButtonSelectAllChildren_CheckedChanged);
        this.radioButtonSetBooksAsCurrent.AutoSize = true;
        this.radioButtonSetBooksAsCurrent.Location = new System.Drawing.Point(163, 258);
        this.radioButtonSetBooksAsCurrent.Size = new System.Drawing.Size(120, 17);
        this.radioButtonSetBooksAsCurrent.Text = "Set Books as current";
        this.radioButtonSetBooksAsCurrent.CheckedChanged += new System.EventHandler(this.radioButtonSetBooksAsCurrent_CheckedChanged);
        this.radioButtonSetBookAsCurrent.AutoSize = true;
        this.radioButtonSetBookAsCurrent.Location = new System.Drawing.Point(163, 234);
        this.radioButtonSetBookAsCurrent.Size = new System.Drawing.Size(115, 17);
        this.radioButtonSetBookAsCurrent.Text = "Set Book as current";
        this.radioButtonSetBookAsCurrent.CheckedChanged += new System.EventHandler(this.radioButtonSetBookAsCurrent_CheckedChanged);
        this.radioButtonSelectAllBooks.AutoSize = true;
        this.radioButtonSelectAllBooks.Location = new System.Drawing.Point(13, 306);
        this.radioButtonSelectAllBooks.Size = new System.Drawing.Size(96, 17);
        this.radioButtonSelectAllBooks.Text = "Select all books";
        this.radioButtonSelectAllBooks.CheckedChanged += new System.EventHandler(this.radioButtonSelectAllBooks_CheckedChanged);
        this.radioButtonSelectSpecificAuthor.AutoSize = true;
        this.radioButtonSelectSpecificAuthor.Location = new System.Drawing.Point(13, 282);
        this.radioButtonSelectSpecificAuthor.Size = new System.Drawing.Size(137, 17);
        this.radioButtonSelectSpecificAuthor.Text = "Select by specific author";
        this.radioButtonSelectSpecificAuthor.CheckedChanged += new System.EventHandler(this.radioButtonSelectSpecificAuthor_CheckedChanged);
        this.radioButtonSelectAllAuthors.AutoSize = true;
        this.radioButtonSelectAllAuthors.Location = new System.Drawing.Point(13, 258);
        this.radioButtonSelectAllAuthors.Margin = new System.Windows.Forms.Padding(3, 1, 3, 3);
        this.radioButtonSelectAllAuthors.Size = new System.Drawing.Size(102, 17);
        this.radioButtonSelectAllAuthors.Text = "Select all authors";
        this.radioButtonSelectAllAuthors.CheckedChanged += new System.EventHandler(this.radioButtonSelectAllAuthors_CheckedChanged);
        this.textBoxQuery.Location = new System.Drawing.Point(13, 330);
        this.textBoxQuery.Size = new System.Drawing.Size(385, 20);
        this.buttonExecute.Location = new System.Drawing.Point(323, 234);
        this.buttonExecute.Text = "Execute";
        this.buttonExecute.Click += new System.EventHandler(this.buttonExecute_Click);
        this.buttonClose.Location = new System.Drawing.Point(405, 13);
        this.buttonClose.Text = "Close";
        this.buttonClose.Click += new System.EventHandler(this.buttonClose_Click);
        this.listBoxResult.FormattingEnabled = true;
        this.listBoxResult.Location = new System.Drawing.Point(13, 13);
        this.listBoxResult.Size = new System.Drawing.Size(385, 212);
        this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
        this.ClientSize = new System.Drawing.Size(492, 362);
        this.Controls.Add(this.listBoxResult);
        this.Controls.Add(this.buttonClose);
        this.Controls.Add(this.buttonExecute);
        this.Controls.Add(this.textBoxQuery);
        this.Controls.Add(this.radioButtonSelectAllAuthors);
        this.Controls.Add(this.radioButtonSelectSpecificAuthor);
        this.Controls.Add(this.radioButtonSelectAllBooks);
        this.Controls.Add(this.radioButtonSetBookAsCurrent);
        this.Controls.Add(this.radioButtonSetBooksAsCurrent);
        this.Controls.Add(this.radioButtonSelectAllChildren);
        this.Controls.Add(this.radioButtonSelectRoot);
        this.Text = "XPath Queries";
        this.ResumeLayout(false);
        this.PerformLayout();
    }

    private System.Windows.Forms.RadioButton radioButtonSelectRoot;
    private System.Windows.Forms.RadioButton radioButtonSelectAllChildren;
    private System.Windows.Forms.RadioButton radioButtonSetBooksAsCurrent;
    private System.Windows.Forms.RadioButton radioButtonSetBookAsCurrent;
    private System.Windows.Forms.RadioButton radioButtonSelectAllBooks;
    private System.Windows.Forms.RadioButton radioButtonSelectSpecificAuthor;
    private System.Windows.Forms.RadioButton radioButtonSelectAllAuthors;
    private System.Windows.Forms.TextBox textBoxQuery;
    private System.Windows.Forms.Button buttonExecute;
    private System.Windows.Forms.Button buttonClose;
    private System.Windows.Forms.ListBox listBoxResult;
    [STAThread]
    static void Main() {
        Application.EnableVisualStyles();
        Application.Run(new Form1());
    }
}


XPath Expression Syntax

Expression   Description
/            Starts an absolute path that selects from the root node.
             /Order/Items/Item selects all Item elements that are children of an Items element, 
             which is itself a child of the root Order element.
//           Starts a relative path that selects nodes anywhere.
             //Item/Name selects all the Name elements that are children of an Item element, 
             regardless of where they appear in the document.
@            Selects an attribute of a node.
             /Order/@id selects the attribute named id from the root Order element.
*            Selects any element in the path.
             /Order/* selects both Items and Client nodes because both are contained by a root 
             Order element.
|            Combines multiple paths.
             
             /Order/Items/Item/Name|Order/Client/Name selects the Name nodes used to describe 
             a Client and the Name nodes used to describe an Item.
.            Indicates the current (default) node.
             If the current node is an Order, the expression ./Items refers to the related 
             items for that order.
..           Indicates the parent node.
             //Name/.. selects any element that is parent to a Name, which includes the Client 
             and Item elements.
[ ]          Define selection criteria that can test a contained node or attribute value.
             /Order[@id="1999-01-30.195496"] selects the Order elements with the indicated 
             attribute value.
             /Order/Items/Item[Price > 50] selects products above $50 in price.
             /Order/Items/Item[Price > 50 and Name="Laser Printer"] selects products that match 
             two criteria.
starts-with  This function retrieves elements based on what text a contained element starts with.
             /Order/Items/Item[starts-with(Name, "C")] finds all Item elements that have a 
             Name element that starts with the letter C.
position     This function retrieves elements based on position.
             /Order/Items/Item[position ()=2] selects the second Item element.
count        This function counts elements. You specify the name of the child element to count or 
             an asterisk (*) for all children.
             /Order/Items/Item[count(Price) = 1] retrieves Item elements that have exactly one 
             nested Price element.


XPathNavigator

using System;
using System.Collections.Generic;
using System.ruponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Xml.XPath;
public class MainClass {
    public static void Main() {
        XPathDocument doc = new XPathDocument("books.xml");
        XPathNavigator nav = ((IXPathNavigable)doc).CreateNavigator();
        XPathNodeIterator iter = nav.Select("/bookstore/book[@genre="novel"]");
        while (iter.MoveNext()) {
            XPathNodeIterator newIter = iter.Current.SelectDescendants(XPathNodeType.Element, false);
            while (newIter.MoveNext())
                Console.WriteLine(newIter.Current.Name + ": " + newIter.Current.Value);
        }
    }
}


XPathNodeIterator

using System;
using System.Collections.Generic;
using System.ruponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Xml.XPath;
public class MainClass {
    public static void Main() {
        XPathDocument doc = new XPathDocument("books.xml");
        XPathNavigator nav = ((IXPathNavigable)doc).CreateNavigator();
        XPathNodeIterator iter = nav.Select("/bookstore/book");
        while (iter.MoveNext()) {
            XPathNodeIterator newIter = iter.Current.SelectDescendants(XPathNodeType.Element, false);
            while (newIter.MoveNext())
                Console.WriteLine(newIter.Current.Name + ": " + newIter.Current.Value);
        }
        Console.WriteLine("Total Cost = " + nav.Evaluate("sum(/bookstore/book/price)"));
    }
}


XPath Query Demo

using System;
using System.Xml;
using System.Xml.XPath;
public class XPathQuery {
  public static void Main(string [] args) {
    string filename = "inventory.xml";
    string xpathExpression = "//inventory/items";
    XmlDocument document = new XmlDocument( );
    document.Load(filename);
    XmlTextWriter writer = new XmlTextWriter(Console.Out);
    writer.Formatting = Formatting.Indented;
    XmlNode node = document.SelectSingleNode(xpathExpression);
    node.WriteTo(writer);
    writer.Close( );
  }
}
/*
<inventory>
  <date year="2006" month="8" day="27" />
  <items>
    <item quantity="5" productCode="01" description="PHP"  unitCost="9.95" />
    <item quantity="3" productCode="02" description="Perl" unitCost="4.95" />
  </items>
</inventory>
*/