maxp
maxp

Reputation: 25141

Neatest way to extract 'text' value from an XmlNode?

Given the code:

  var doc = new XmlDocument();
  doc.LoadXml(@"<a>
                    <b>test
                        <c>test2</c>
                    </b>
                </a>");
  var node = doc.SelectNodes("/a/b")[0];

I want to then extract the 'text' value of node b - in this case "test", without retrieving all text elements from all child nodes (as .innerText does)

I find myself resorting to this code

 var elementText = node.ChildNodes.Cast<XmlNode>().First(a => a.NodeType == XmlNodeType.Text).Value;

As unfortunately node.Value does something else in this case

is there a neater/inbuilt way without resorting to linq casting? that doesnt involve me doing something like;

foreach (var childNode in node.ChildNodes)
   if (childNode.NodeType==XmlNodeType.Text)
    ...

Upvotes: 2

Views: 234

Answers (3)

Dave Zych
Dave Zych

Reputation: 21887

I prefer XDocument to XmlDocument, I think it's easier to work with. You can easily get a value using the Element method to find the "b" element, and then using the Value property.

using(var stream = new MemoryStream())
{
    using(var streamWriter = new StreamWriter(stream))
    {
        streamWriter.Write(@"<a>
                                 <b>test
                                     <c>test2</c>
                                 </b>
                             </a>");
        streamWriter.Flush();
        streamWriter.BaseStream.Seek(0, SeekOrigin.Begin);
        var doc = XDocument.Load(stream);
        Console.WriteLine(doc.Element("a").Element("b").FirstNode.ToString());
    }
}

EDIT: As noted in comments, that would get the incorrect value. I've updated it correctly.

Upvotes: 4

Jetti
Jetti

Reputation: 2458

You want to use node.InnerText instead of Value. So you would have this:

 foreach(XmlNode child in node.ChildNodes)
 {
    if (string.IsNullOrEmpty(s))
    {
        s = child.InnerText;
    }
    else
    {
        s = s.Replace(child.InnerText, "");
    }
 }

   s.Trim();

Upvotes: 0

Anirudha
Anirudha

Reputation: 32787

In LINQ2XML you can do this

foreach(XNode elm in doc.Descendants("b").OfType<XText>())
{
//elm has the text
}

Upvotes: 0

Related Questions