2
<?xml version="1.0" encoding="ISO-8859-1"?>
 <bookstore>
  <book category="COOKING"> 
    <title lang="en">Everyday Italian</title>
    <author>Giada De Laurentiis</author>    
    <year>2005</year>
   <price>30.00</price>
  </book>

  <book category="CHILDREN">
   <title lang="en">Harry Potter</title>
   <author>J K. Rowling</author>
   <year>2005</year>
   <price>29.99</price>
  </book>

  <book category="WEB">
   <title lang="en">XQuery Kick Start</title>
   <author>James McGovern</author>
   <author>Per Bothner</author>
   <author>Kurt Cagle</author>
   <author>James Linn</author>
   <author>Vaidyanathan Nagarajan</author>
   <year>2003</year>
   <price>49.99</price>
  </book>

  <book category="WEB">
   <title lang="en">Learning XML</title>
   <author>Erik T. Ray</author>
   <year>2003</year>
   <price>39.95</price>
  </book>

</bookstore>

Is their any way using XPath to select the complete first node set, for example from

 <book category="COOKING">  
  to 
 </book>, 

so that, that chunk of xml can be stored for later use.

Bob.

scope_creep
  • 4,213
  • 11
  • 35
  • 64

4 Answers4

3

Let's say this XML is stored in an XmlDocument called doc.

XmlElement docRoot = doc.DocumentElement;
XmlNode cookingNode = docRoot.SelectSingleNode("./book[@category='COOKING']");

I tested this and added this line to verify:

Console.WriteLine(cookingNode.OuterXml);

Here was the output:

<book category="COOKING"><title lang="en">Everyday Italian</title><author>Giada
De Laurentiis</author><year>2005</year><price>30.00</price></book>
Dan Tao
  • 125,917
  • 54
  • 300
  • 447
1

This query will select that node. Are you trying to get a set of nodes or just the single one? You might have to put the bookstore node back yourself if you only want th subset of nodes.

/bookstore/book[@category='COOKING']

as XmlDocument ...

var x = new XmlDocument();
x.Load("XmlFile1.xml");
var ns = x.SelectSingleNode("/bookstore/book[@category='COOKING']");

var res = ns.OuterXml;

as XDocument ...

var x = XDocument.Load("XmlFile1.xml");

var root = new XElement("bookstore",
    from book in x.Element("bookstore").Elements("book")
    where book.Attribute("category").Value == "COOKING"
    select book
    );

if you just want the book node you can do this instead of the root version above

var book = x.Element("bookstore")
    .Elements("book")
    .Where(n => n.Attribute("category").Value == "COOKING")
    .First();
Matthew Whited
  • 22,160
  • 4
  • 52
  • 69
  • I've tried that. That only brings back the "COOKING NODE". What I want is to bring back everything that is inside that particular block from to ... – scope_creep Oct 02 '09 at 19:42
  • I'm reading xml messages coming into a message pipe. I need to store specific parts of them, so those parts can be built up into a new composite message, essentially a request/reply. So I need a way to picking selected chunks of xml from incoming messages to be used at a later date to build the reply message. – scope_creep Oct 02 '09 at 19:44
  • I am getting the entire node with SelectNode and SelectSingleNode. The Xml.Linq classes are working the same. – Matthew Whited Oct 02 '09 at 19:47
  • @scope-creep: From `var ns = x.SelectSingleNode([...])`, you should be able to access the nodes inside that node with `ns.ChildNodes`. – Dan Tao Oct 02 '09 at 19:50
  • Also you can check the .OuterXml it will show you the node you are on. If you sheck .InnerXML it will only show you the children. – Matthew Whited Oct 02 '09 at 20:00
1

suppose I want to extract only the data wherethe xml file is as follows ..

<book category="COOKING"> 
    <title lang="en">Everyday Italian</title>
    <author auth="up">Giada De Laurentiis</author>    
    <year>2005</year>
   <price>30.00</price>
  </book>

the final result on the list view should look like this

  lang       auth
  en          up

I have coded as follows ..

XmlNodeList elemList = doc.GetElementsByTagName("book");
                    for (int j = 0; j < elemList.Count; j++)
                    {
                        if (elemList[j].Attributes["category"].Value == "COOKING")
                        {
                            XmlNodeList elemList1 = doc.GetElementsByTagName("author");
                            for (int i = 0; i < elemList1.Count; i++)
                            {
                                string attrVal = elemList1[i].Attributes["lang"].Value;
                                string attrVal1 = elemList1[i].Attributes["auth"].Value;

                                ListViewItem lvi = new ListViewItem();

                                    lvi.SubItems.Add(attrVal1);
                                    lvi.SubItems.Add(attrVal1);
                                }
                                listView1.Items.Add(lvi);
                            }
                        }
                    }
Gifted
  • 31
  • 1
  • 9
  • finally I hav the code for the requirement I had .. `XmlDocument xDoc = new XmlDocument(); // (Put code to populate xDoc here) XmlNodeList xNode = xDoc.SelectNodes(@"/bookstore/book[@category='COOKING']/title");` – Gifted Mar 14 '13 at 15:58
0

Adding to Matthew's response:

XmlDocument xDoc = new XmlDocument();
// (Put code to populate xDoc here)
XmlNodeList xNode = xDoc.SelectNodes(@"/bookstore/book[@category='COOKING']");

xNode now equals Book of type COOKING.

tsilb
  • 7,977
  • 13
  • 71
  • 98