2009-02-20 161 views
27

考虑下面的XML片段:如何通过XPath检索CDATA标记中的元素文本?

<Obj> 
    <Name><![CDATA[SomeText]]></Name> 
</Obj> 

如何检索通过的XPath的 “SomeText” 则会价值?我正在使用Nauman Leghari的(优秀)Visual XPath tool
/Obj/Name返回元素
/Obj/Name/text()回报空白

我不认为它与工具(我可能是错的)一个问题 - 我也看到的XPath不能提取CDATA(见最后响应in this thread) - 这听起来对我来说有点奇怪。

回答

8

我想你提到的线程说,CDATA标记本身是由XPATH忽略,不包含在CDATA标记的文字。

我的猜测是,它与工具的问题,源代码可供下载,也许你可以调试它...

+1

它基本上是对的XMLNode的扫描类型巨人DisplayNode()开关的情况下.. 。与特定的情况下阻止与TODO里面:)问题与它的工具。 – Gishu 2009-04-24 14:38:39

9

CDATA节只是什​​么XPath称为text nodethe XML Infoset作为“字符信息项的块”的一部分。

显然,您的工具是错误的。其他工具,如the XPath Visualizer评估该XPath表达式时,正确突出Name元素的文本:

/*/Name/text() 

你也可以写一个简单的XSLT转换:当应用这种转变

<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> 

在提供的XML文档上

<Obj> 
    <Name><![CDATA[SomeText]]></Name> 
</Obj> 

正确的结果产生:

"SomeText" 
19

/Obj/Name/text()是XPath返回CDATA标记的内容。

什么扔我是Value属性的行为。对于XMLNode(DOM世界),Element(带有CDATA或其他)的XmlNode.Value属性返回Null。 InnerText属性会给你CDATA /文本内容。 如果使用Xml.Linq,则XElement.Value将返回CDATA内容。

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")); 

输出:

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 

竟然视觉的XPath笔者曾经为CDATA类型将XMLNode TODO。一段代码片段,我现在有CDATA支持。 alt text

的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; 
+1

> Value属性的行为 您会看到不同API反映的不同数据模型的影响。许多API遵循XML Infoset来区分文本和CData内容。但XPath不会。 .NET的XPathDocument API遵循XPath模型,因此您不能明确地看到CDATA, – Richard 2009-02-21 18:58:59

-3

一个建议是将cdata的md5散列的另一个字段。然后,您可以使用XPath查询基于断MD5没有问题

<sites> 
    <site> 
    <name>Google</name> 
    <url><![CDATA[http://www.google.com]]></url> 
    <urlMD5>ed646a3334ca891fd3467db131372140</urlMD5> 
    </site> 
</sites> 

然后,你可以搜索:

/sites/site[urlMD5=ed646a3334ca891fd3467db131372140] 
+0

如果xpath表示法允许直接搜索相关的节点,则不需要此:-) – 2016-09-28 08:06:46

相关问题