¿Cómo recupero el texto del elemento dentro de la marca CDATA a través de XPath?

Considere el siguiente fragmento xml:

   

¿Cómo recupero el valor “SomeText” a través de XPath? Estoy usando la excelente herramienta Visual XPath de Nauman Leghari.
/Obj/Name devuelve el elemento
/Obj/Name/text() devuelve un espacio en blanco

No creo que sea un problema con la herramienta (puedo estar equivocado). También leo que XPath no puede extraer CDATA (ver la última respuesta en este hilo ), lo cual me suena un poco raro.

Creo que el hilo al que se hace referencia dice que el marcado CDATA es ignorado por XPATH, no el texto contenido en el marcado CDATA.

mi suposición es que es un problema con la herramienta, el código fuente está disponible para descargar, quizás puedas depurarlo …

/Obj/Name/text() es el XPath para devolver el contenido del marcado CDATA.

Lo que me sorprendió fue el comportamiento de la propiedad Value. Para un XMLNode (mundo DOM), la propiedad XmlNode.Value de un elemento (con CDATA u otro) devuelve nulo. La propiedad InnerText le daría el contenido CDATA / Text. Si usa Xml.Linq, XElement.Value devuelve el contenido CDATA.

 string sXml = @"   OtherName "; 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") ); 

Salida:

 XPath = /object/name NodeType = Element Value =  OuterXml =  InnerXml =  InnerText = SomeText NodeType = Element Value =  OuterXml = OtherName InnerXml = OtherName InnerText = OtherName XPath = /object/name/text() NodeType = CDATA Value = SomeText OuterXml =  InnerXml = InnerText = SomeText NodeType = Text Value = OtherName OuterXml = OtherName InnerXml = InnerText = OtherName Xml.Linq = obRoot.Elements("name") Value = SomeText Value = OtherName 

Resultó que el autor de Visual XPath tenía un TODO para el tipo CDATA de XmlNodes. Un pequeño fragmento de código y ahora tengo soporte para CDATA. texto alternativo

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; 

Las secciones CDATA son solo una parte de lo que XPath se conoce como un text node o en el Infoset XML como “fragmentos de elementos de información de caracteres”.

Obviamente, tu herramienta está equivocada . Otras herramientas, como XPath Visualizer resaltan correctamente el texto del elemento Name al evaluar esta expresión XPath:

 /*/Name/text() 

También se puede escribir una transformación XSLT simple :

    ""   

Cuando esta transformación se aplica en el documento XML proporcionado :

    

el resultado correcto es producido:

  "SomeText" 

Vea si esto ayuda – http://www.zrinity.com/xml/xpath/
XPATH = / Obj / Nombre / texto ()

Una sugerencia sería tener otro campo del hash md5 del cdata. A continuación, puede usar xpath para realizar consultas basadas en el md5 sin problemas

   Google  ed646a3334ca891fd3467db131372140   

Luego puedes buscar:

 /sites/site[urlMD5=ed646a3334ca891fd3467db131372140]