Tom Squires
Tom Squires

Reputation: 9296

Using xpath with c#, help

I'm trying to select the content of MINRANGE of the below XML. This is the code I'm using, the string min just gives me a long block of text not the node i wanted.

XPathDocument _BTCall = new XPathDocument(callUrl);
XPathNavigator nav = _BTCall.CreateNavigator();
XPathExpression exp;
exp = nav.Compile("//MAX/MINRANGE");
XPathNodeIterator iterator = nav.Select(exp);
iterator.MoveNext();

XPathNavigator nav2 = iterator.Current.Clone();
string min = nav.Value;
return int.Parse(min);

<ADSL_CHECKER>
  <ERRORID>0</ERRORID>
  <INPUT>01491410786</INPUT>
  <INPUTTYPE>TELNO</INPUTTYPE>
  <FIXEDRATE>
    <RAG>G</RAG>
    <READYDATE />
    <EXCHSTATE>E</EXCHSTATE>
    <CAPACITY />
  </FIXEDRATE>
  <RATEADAPTIVE>
    <RAG>G</RAG>
    <READYDATE />
    <EXCHSTATE>E</EXCHSTATE>
    <CAPACITY />
  </RATEADAPTIVE>
  <MAX>
    <RAG>G</RAG>
    <SPEED>4500</SPEED>
    <MINRANGE>3500</MINRANGE>
    <MAXRANGE>5500</MAXRANGE>
    <READYDATE />
    <EXCHSTATE>E</EXCHSTATE>
    <CAPACITY />
  </MAX>
  <WBC>
    <RAG>G</RAG>
    <SPEED>5500</SPEED>
    <MINRANGE>4500</MINRANGE>
    <MAXRANGE>6500</MAXRANGE>
    <READYDATE />
    <EXCHSTATE>E</EXCHSTATE>
    <CAPACITY />
  </WBC>
  <WBCFTTC>
    <RAG>G</RAG>
    <DOWNSPEED>32500</DOWNSPEED>
    <UPSPEED>7200</UPSPEED>
    <MINRANGE />
    <MAXRANGE />
    <READYDATE />
    <EXCHSTATE>E</EXCHSTATE>
    <CAPACITY />
  </WBCFTTC>
  <EXCHANGECODE>THHT</EXCHANGECODE>
  <EXCHANGENAME>HENLEY-ON-THAMES</EXCHANGENAME>
  <REASONCODE>L</REASONCODE>
  <VPCONTENTION>N</VPCONTENTION>
  <SPNAME />
  <CAD />
  <CPNAME>BE UN LIMITED</CPNAME>
  <CPCONTACTNO>02074795000</CPCONTACTNO>
  <POSTCODE>RG9 1LT</POSTCODE>
  <SUGGESTEDMSG>Your exchange is ADSL enabled, and our initial test on your line indicates that your line should be able to have an ADSL broadband service that provides a fixed line speed up to 2Mbps.

    Our test also indicates that your line currently supports an estimated ADSL Max broadband line speed of 4.5Mbps. Similar lines predicted with this speed have achieved ADSL Max line speeds in the range of 3.5 to 5.5Mbps.
    Our test also indicates that your line currently supports an estimated ADSL2+ broadband line speed of 5.5Mbps. Similar lines predicted with this speed have achieved ADSL2+ line speed in the range of 4.5 to 6.5Mbps.
    Our test also indicates that your line currently supports a fibre technology with an estimated WBC FTTC Broadband where consumers have received downstream line speed of 32.5Mbps and upstream line speed of 7.2Mbps.
    The actual stable line speed supportable will be determined during the first 10 days of use. This speed may change over time, to ensure line stability is maintained.
    If you decide to place an order, a further test will be performed to confirm if your line is suitable for the service you wish to purchase.
    Thank you for your interest.
    Please note that postcode and address check results are indicative only. Most accurate results can be obtained from a telephone number check.
  </SUGGESTEDMSG>
  <SUPPLEMENTARYMSG>Note: If you already have a Broadband service enabled on this line and you want to switch service providers, you will need to contact both your current provider and your new provider to get your service changed over new and existing service provider to have this service transferred.
  </SUPPLEMENTARYMSG>
</ADSL_CHECKER>

Text in XML was modified slightly for formatting purposes. See previous version for exact.

Upvotes: 1

Views: 193

Answers (4)

C. Ross
C. Ross

Reputation: 31878

You need to capture the result of iterator.MoveNext().

XPathNodeIterator iterator = nav.Select(exp);
if (iterator.MoveNext())
{
   XPathNavigator res = iterator.Current;
   string min = res.Value;
}
else 
{
   //Error
}

The iterator.MoveNext() doesn't modify your original nav object.

Upvotes: 1

David Anderson
David Anderson

Reputation: 13690

There are actually quite a few different methods of selecting the content of an XmlNode. Let me share a few. (You can of course modify the code to use a String of Xml instead of loading from an Xml file)

Using an XmlDocument object and SelectSingleNode()

//-----------------------------------------------------------------------------
// <copyright file="Program.cs" company="DCOM Productions">
//     Copyright (c) DCOM Productions.  All rights reserved.
// </copyright>
//-----------------------------------------------------------------------------

namespace ConsoleApplication1 {
    using System;
    using System.Xml;

    class Program {
        static void Main(string[] args) {
            XmlDocument xdoc = new XmlDocument();
            try {
                xdoc.Load(".\\App.xml");
            }
            catch (System.Xml.XmlException ex) {
                // handle
            }
            XmlNode node = xdoc.SelectSingleNode("ADSL_CHECKER//MAX//MINRANGE");
            Console.WriteLine(node.InnerText);
            Console.ReadKey(true);
        }
    }
}

Using an XDocument object and Element()

//-----------------------------------------------------------------------------
// <copyright file="Program.cs" company="DCOM Productions">
//     Copyright (c) DCOM Productions.  All rights reserved.
// </copyright>
//-----------------------------------------------------------------------------

namespace ConsoleApplication1 {
    using System;
    using System.Xml;
    using System.Xml.Linq;

    class Program {
        static void Main(string[] args) {
            XDocument xdoc = XDocument.Load(".\\App.xml");
            XElement element = xdoc.Element("ADSL_CHECKER").Element("MAX").Element("MINRANGE");
            Console.WriteLine(element.Value);
            Console.ReadKey(true);
        }
    }
}

Using an XDocument object and LINQ query

//-----------------------------------------------------------------------------
// <copyright file="Program.cs" company="DCOM Productions">
//     Copyright (c) DCOM Productions.  All rights reserved.
// </copyright>
//-----------------------------------------------------------------------------

namespace ConsoleApplication1 {
    using System;
    using System.Linq;
    using System.Xml;
    using System.Xml.Linq;

    class Program {
        static void Main(string[] args) {
            XDocument xdoc = XDocument.Load(".\\App.xml");
            var result = from e in xdoc.Element("ADSL_CHECKER").Element("MAX").Elements()
                         where e.Name == "MINRANGE"
                         select e;
            Console.WriteLine(result.First().Value);
            Console.ReadKey(true);
        }
    }
}

It is always important that your XPath's are correct, and as always refer to the Msdn Documentation for help on using XmlDocument and XDocument.

Upvotes: 0

Bashir Magomedov
Bashir Magomedov

Reputation: 2891

Use XmlDocument instance and load your XML into it, and then use SelectNodes method passing your xpath query as an input parameter.

        XmlDocument xmlDocument = new XmlDocument();
        xmlDocument.LoadXml(xmlText);
        var gg = xmlDocument.SelectNodes("//MAX/MINRANGE");

This will give you a collection of nodes you can iterate through.

Upvotes: 2

Andy
Andy

Reputation: 8562

What version of the .Net framework are you using? If you're using 3.5 or higher, I strongly recommend using Linq to work with the Xml, you'll have a much easier time. Check out the XDocument and related classes.

http://msdn.microsoft.com/en-us/library/bb387044.aspx

Upvotes: 2

Related Questions