Shantanu Banerjee
Shantanu Banerjee

Reputation: 1447

Xpath select query with also relative top level node in c#

I am using xpath to query my xml file in C#.

Here is my xml file

<?xml version="1.0" encoding="ISO-8859-1"?>

<bookstore>

<book>
  <title lang="eng">Harry Potter</title>
  <price>29.99</price>
</book>

<book>
  <title lang="eng">Learning XML</title>
  <price>39.95</price>
</book>

</bookstore>

And my C# code is

XPathNavigator nav;
XPathDocument docNav;
XPathNodeIterator NodeIter;
String strExpression;

docNav = new XPathDocument(@"C:\\DCU\\XQUE.xml");

nav = docNav.CreateNavigator();
// This expression uses standard XPath syntax.

strExpression = "/bookstore[./book/price>35.00]";

NodeIter = nav.Select(strExpression);

while (NodeIter.MoveNext())
{
    Console.WriteLine("{0}", NodeIter.Current.OuterXml);
}

But I want to get output like this,

<bookstore>
<book>
  <title lang="eng">Learning XML</title>
  <price>39.95</price>
</book>
</bookstore>

I think anything missing with my xpath query line, please lead me a way out..

Upvotes: 0

Views: 605

Answers (2)

JLRishe
JLRishe

Reputation: 101738

It seems that you're misunderstanding the purpose of XPath selection and what it can do. XPath won't create a whole new XML document for you. The typical choice for taking an XML input and producing a different XML output is to use XSLT. This would do it in your case:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>

  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="book[price &lt;= 35]" />
</xsl:stylesheet>

If you really want to use just C# to do this, you could always do the following:

XPathNavigator nav;
XPathDocument docNav;
XPathNodeIterator NodeIter;
String strExpression;

docNav = new XPathDocument(@"C:\\DCU\\XQUE.xml");

nav = docNav.CreateNavigator();
// This expression uses standard XPath syntax.

strExpression = "/bookstore/book[price > 35.00]";

NodeIter = nav.Select(strExpression);

Console.WriteLine("<bookstore>");
while (NodeIter.MoveNext())
{
    Console.WriteLine("{0}", NodeIter.Current.OuterXml);
}
Console.WriteLine("</bookstore>");

Upvotes: 1

Ian Roberts
Ian Roberts

Reputation: 122394

That expression selects <bookstore> elements, so the output will be the whole <bookstore> (with all its child book elements). If you want specific books you need to use a different XPath

strExpression = "/bookstore/book[price>35.00]";

which will print just the <book> elements that match, but without the surrounding <bookstore> tags.

Upvotes: 1

Related Questions