2009-02-20 75 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

相關問題