Reputation: 25141
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
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
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
Reputation: 32787
In LINQ2XML you can do this
foreach(XNode elm in doc.Descendants("b").OfType<XText>())
{
//elm has the text
}
Upvotes: 0