How do I retrieve element text inside CDATA markup via XPath?
Solution 1
i think the thread you referenced says that the CDATA markup itself is ignored by XPATH, not the text contained in the CDATA markup.
my guess is that its an issue with the tool, the source code is available for download, maybe you can debug it...
Solution 2
/Obj/Name/text()
is the XPath to return the content of the CDATA markup.
What threw me off was the behavior of the Value property. For an XMLNode (DOM world), the XmlNode.Value property of an Element (with CDATA or otherwise) returns Null. The InnerText property would give you the CDATA/Text content. If you use Xml.Linq, XElement.Value returns the CDATA content.
string sXml = @"
<object>
<name><![CDATA[SomeText]]></name>
<name>OtherName</name>
</object>";
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml( sXml );
XmlNamespaceManager nsMgr = new XmlNamespaceManager(xmlDoc.NameTable);
Console.WriteLine(@"XPath = /object/name" );
WriteNodesToConsole(xmlDoc.SelectNodes("/object/name", nsMgr));
Console.WriteLine(@"XPath = /object/name/text()" );
WriteNodesToConsole( xmlDoc.SelectNodes("/object/name/text()", nsMgr) );
Console.WriteLine(@"Xml.Linq = obRoot.Elements(""name"")");
XElement obRoot = XElement.Parse( sXml );
WriteNodesToConsole( obRoot.Elements("name") );
Output:
XPath = /object/name
NodeType = Element
Value = <null>
OuterXml = <name><![CDATA[SomeText]]></name>
InnerXml = <![CDATA[SomeText]]>
InnerText = SomeText
NodeType = Element
Value = <null>
OuterXml = <name>OtherName</name>
InnerXml = OtherName
InnerText = OtherName
XPath = /object/name/text()
NodeType = CDATA
Value = SomeText
OuterXml = <![CDATA[SomeText]]>
InnerXml =
InnerText = SomeText
NodeType = Text
Value = OtherName
OuterXml = OtherName
InnerXml =
InnerText = OtherName
Xml.Linq = obRoot.Elements("name")
Value = SomeText
Value = OtherName
Turned out the author of Visual XPath had a TODO for the CDATA type of XmlNodes. A little code snippet and I have CDATA support now.
MainForm.cs
private void Xml2Tree( TreeNode tNode, XmlNode xNode)
{
...
case XmlNodeType.CDATA:
//MessageBox.Show("TODO: XmlNodeType.CDATA");
// Gishu
TreeNode cdataNode = new TreeNode("![CDATA[" + xNode.Value + "]]");
cdataNode.ForeColor = Color.Blue;
cdataNode.NodeFont = new Font("Tahoma", 12);
tNode.Nodes.Add(cdataNode);
//Gishu
break;
Solution 3
CDATA sections are just part of what in XPath is known as a text node
or in the XML Infoset as "chunks of character information items".
Obviously, your tool is wrong. Other tools, as the XPath Visualizer correctly highlight the text of the Name
element when evaluating this XPath expression:
/*/Name/text()
One can also write a simple XSLT transformation:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
"<xsl:value-of select="/*/Name"/>"
</xsl:template>
</xsl:stylesheet>
When this transformation is applied on the provided XML document:
<Obj>
<Name><![CDATA[SomeText]]></Name>
</Obj>
the correct result is produced:
"SomeText"
Solution 4
See if this helps - http://www.zrinity.com/xml/xpath/
XPATH = /Obj/Name/text()
Gishu
Developer - I like to build things and see them work. Gimme a good book or a game and I can keep myself out of trouble. Got hooked on TDD-XP-Agile around 2005.. trying to get to the promised land since. Work with C Based languages. Play with Ruby.
Updated on April 08, 2020Comments
-
Gishu about 4 years
Consider the following xml fragment:
<Obj> <Name><![CDATA[SomeText]]></Name> </Obj>
How do I retrieve the "SomeText" value via XPath? I'm using Nauman Leghari's (excellent) Visual XPath tool.
/Obj/Name
returns the element
/Obj/Name/text()
returns blankI don't think its a problem with the tool (I may be wrong) - I also read XPath can't extract CDATA (See last response in this thread) - which sounds kinda weird to me.