Considérez le fragment xml suivant:
<Obj>
<Name><![CDATA[SomeText]]></Name>
</Obj>
Comment récupérer la valeur "SomeText" via XPath? J'utilise Nauman Leghari (excellent) outil Visual XPath ./Obj/Name
Renvoie l'élément/Obj/Name/text()
renvoie vide
Je ne pense pas que ce soit un problème avec l'outil (je peux me tromper) - J'ai également lu que XPath ne peut pas extraire CDATA (Voir la dernière réponse dans ce fil ) - ce qui me semble un peu bizarre.
je pense que le fil que vous avez référencé dit que le balisage CDATA lui-même est ignoré par XPATH, pas le texte contenu dans le balisage CDATA.
je suppose que c'est un problème avec l'outil, le code source est disponible pour téléchargement, peut-être que vous pouvez le déboguer ...
/Obj/Name/text()
est le XPath pour renvoyer le contenu du balisage CDATA.
Ce qui m'a bouleversé, c'est le comportement de la propriété Value. Pour un XMLNode (monde DOM), la propriété XmlNode.Value d'un élément (avec CDATA ou autre) renvoie Null. La propriété InnerText vous donnerait le contenu CDATA/texte. Si vous utilisez Xml.Linq, XElement.Value renvoie le contenu 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") );
Production:
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
Il s'est avéré que l'auteur de Visual XPath avait un TODO pour le type CDATA de XmlNodes. Un petit extrait de code et j'ai maintenant le support CDATA.
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;
Les sections CDATA ne sont qu'une partie de ce que dans XPath est connu sous le nom de text node
ou dans l'ensemble d'informations XML sous la forme de "blocs d'informations de caractère"
Évidemment, votre outil est erroné . D'autres outils, comme le visualiseur XPath mettent correctement en surbrillance le texte de l'élément Name
lors de l'évaluation de cette expression XPath :
/*/Name/text()
On peut également écrire une simple transformation 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>
Lorsque cette transformation est appliquée sur le document XML fourni :
<Obj>
<Name><![CDATA[SomeText]]></Name>
</Obj>
le résultat correct est produit:
"SomeText"
Voyez si cela aide - http://www.zrinity.com/xml/xpath/
XPATH =/Obj/Nom/texte ()