Si...">

Getting InnerText only the current node using XmlNode

I have an XMLNode whose body looks like this: (via OpenCalais)

<SocialTag importance="2">Signal processing <originalValue>Signal processing</originalValue> </SocialTag> 

When I call XMLMNode.InnerText on it, I return:

 SignalprocessingSignalprocessing 

However, I only need the InnerText from the tag itself, and not the InnerText of the original value for the child node.

When I call XMLNode.Value , it returns null.

How can I get only the InnerText of this node without concatenating all InnerTexts of the other child nodes?

+4
source share
4 answers

The text inside the XmlNode is actually another XmlNode of the text type. This should work:

 socialTagNode.ChildNodes[0].Value 
+8
source

From docs , XmlElement.InnerText

Gets or sets the concatenated values ​​of the node and all its children.

Although this statement is still not entirely clear, it means that the property is moving away from the DOM hierarchy under the element and merging all text values ​​into the return value - the behavior you see.

Extending the accepted answer, here are the extension methods adapted from the reference source that all immediate text children of this node collect and return:

 public static partial class XmlNodeExtensions { /// <summary> /// Returns all immediate text values of the given node, concatenated into a string /// </summary> /// <param name="node"></param> /// <returns></returns> public static string SelfInnerText(this XmlNode node) { // Adapted from http://referencesource.microsoft.com/#System.Xml/System/Xml/Dom/XmlNode.cs,66df5d2e6b0bf5ae,references if (node == null) return null; else if (node is XmlProcessingInstruction || node is XmlDeclaration || node is XmlCharacterData) { // These are overridden in the reference source. return node.InnerText; } else { var firstChild = node.FirstChild; if (firstChild == null) return string.Empty; else if (firstChild.IsNonCommentText() && firstChild.NextSibling == null) return firstChild.InnerText; // Optimization. var builder = new StringBuilder(); for (var child = firstChild; child != null; child = child.NextSibling) { if (child.IsNonCommentText()) builder.Append(child.InnerText); } return builder.ToString(); } } /// <summary> /// Enumerates all immediate text values of the given node. /// </summary> /// <param name="node"></param> /// <returns></returns> public static IEnumerable<string> SelfInnerTexts(this XmlNode node) { // Adapted from http://referencesource.microsoft.com/#System.Xml/System/Xml/Dom/XmlNode.cs,66df5d2e6b0bf5ae,references if (node == null) yield break; else if (node is XmlProcessingInstruction || node is XmlDeclaration || node is XmlCharacterData) { // These are overridden in the reference source. yield return node.InnerText; } else { var firstChild = node.FirstChild; for (var child = firstChild; child != null; child = child.NextSibling) { if (child.IsNonCommentText()) yield return child.InnerText; } } } public static bool IsNonCommentText(this XmlNode node) { return node != null && (node.NodeType == XmlNodeType.Text || node.NodeType == XmlNodeType.CDATA || node.NodeType == XmlNodeType.Whitespace || node.NodeType == XmlNodeType.SignificantWhitespace); } } 

Then use it like:

 var value = XMLMNode.SelfInnerText(); 

Fiddle example.

+1
source

You can try the following: node tag:

 var result=""; var nodes = node.childNodes for (var i=0,len=nodes.length; i<len; i++) { var node=nodes[i]; if (node.nodeType==node.TEXT_NODE) { result += node.nodeValue; } } 

It should cncatenate all text fields inside the main node and ignore children

0
source

So there are a few things:

  • InnerText by definition gives you text for all child nodes. Asking for “InnerText from [just] this node” does not make sense in terms of the tools that the api provides.
  • What you are looking for is a child node of type text (or perhaps CDATA, depending on your circumstances). Most (all?) Times this will be the first ChildNode.
0
source

All Articles