2

I have one XML file and I have created on function for retrieving value from XML nodes. Now the problem is if my node have no inner node, still flow goes inside the recursive sentence !

Have a look in my function

/*
XmlDocument x = new XmlDocument(); x.Load(filename);
*/
   public string getValue(string nodename)
    {

        if (File.Exists(filename))
        {


            foreach (XmlNode xx in x.SelectNodes("//"+nodename))
            {
                if (xx.HasChildNodes)
                    getValue(nodename + "//"+xx.ChildNodes[0].Name);
                else
                    return xx.InnerText;
            }   

        }
        return null;
    }

My xmlfile is

<oodle_response stat="ok">
    <current>
        <region>
            <id>barrie</id>
            <name>Barrie</name>
        </region>
        <start>1</start>
        <num>10</num>
    </current>
</oodle_response>

and I am calling my function through

protected void btnLets_Click(object sender, EventArgs e)
{
   string filename = Server.MapPath("~/xmls/newXmlFile.xml";
   oodleXmlParser ox = new oodleXmlParser(filename);
   Response.Write(ox.getValue("oodle_response"));
}
3
  • In which line it is going to dead loop? Commented Jan 31, 2012 at 16:00
  • foreach (XmlNode xx in x.SelectNodes("//"+nodename)) When flow comes after "id" Commented Jan 31, 2012 at 16:01
  • XmlDocument x = new XmlDocument(); x.Load(filename); Commented Jan 31, 2012 at 16:04

2 Answers 2

1

Now the problem is if my node have no inner node, still flow goes inside the recursive sentence !

It's not quite right, e.g. in

<start>1</start>

'1' will be a XmlNode of type XmlNodeType.Text, so you need to check node type of child node instead(or maybe with) xx.HasChildNodes. I think your method should look like this

public static string getValue(string nodename)
    {

        if (File.Exists(filename))
        {

            int i = 0;
            foreach (XmlNode xx in x.SelectNodes("//" + nodename))
            {                   
                if (xx.HasChildNodes && xx.ChildNodes[i].NodeType == XmlNodeType.Element)
                    return getValue(nodename + "//" + xx.ChildNodes[i].Name);//i'm sure it should return value
                else
                    return xx.InnerText;
                i++;
            }

        }
        return null;
    }
Sign up to request clarification or add additional context in comments.

Comments

0

Your method is not intuitive. It does not get a node value per se, it gets the first node with text content. I'd expect getValue("oodle_response") to get the value of that node i.e. barrie Barrie 1 10.

A better approach would be to make use of the bespoke XML library (include System.Xml) to retrieve a node value using XPath e.g.

var reader = new XmlTextReader("~/xmls/newXmlFile.xml");
var doc = new XmlDocument();
doc.Load(reader);

public string getValue(XmlDocument doc, string nodeName)
{
 var navigator = doc.CreateNavigator();
 return navigator.SelectSingleNode(String.Format("//{0}",nodeName)).Value;
}

You'd need to harden this example so that it can cope with invalid XPath queries, but hopefully you get the idea.

Note that I've also passed in an XmlDocument, as your current method is not easily testable i.e. it loads a file where the filename is not passed into the method.

3 Comments

Also note that I've added "xml" as an input parameter, just to make the intent of this code snippet clear.
Impressive answer ! But in case of your "idea" we need to give node name and if that node have inner-nodes then ??
What I'm trying to convey is that your method is not intuitive.The getValue method should get the value for the node you specify, not just get the value of the first text node it encounters!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.