tags:

views:

910

answers:

3
<?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.

+1  A: 

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
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 <book category="Coooking"> to ... <book />
scope_creep
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
I am getting the entire node with SelectNode and SelectSingleNode. The Xml.Linq classes are working the same.
Matthew Whited
@scope-creep: From `var ns = x.SelectSingleNode([...])`, you should be able to access the nodes inside that node with `ns.ChildNodes`.
Dan Tao
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
A: 

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
I think that'll give you an `XmlNodeList` rather than an `XmlNode`.
Dan Tao
Yeah... you will need to get the first index or use SelectSingleNode
Matthew Whited
+2  A: 

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
Thanks Dan.Bob.
scope_creep