Comment récupérer le texte de L'élément dans le balisage CDATA via XPath?
Considérons le fragment xml suivant:
<Obj>
<Name><![CDATA[SomeText]]></Name>
</Obj>
Comment récupérer la valeur" SomeText " via XPath? J'utilise L'outil Visual XPath de Nauman Leghari (excellent) ./Obj/Name
retourne l'élément/Obj/Name/text()
retourne vide
Je ne pense pas que ce soit un problème avec l'outil (je peux me tromper) - j'ai aussi lu que XPath ne peut pas extraire CDATA (voir la dernière réponse dans ce fil) - ce qui me semble un peu bizarre.
5 réponses
Je pense que le thread 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 en 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 jeté était le comportement de la propriété Value. Pour un XmlNode (monde DOM), le XmlNode.La propriété Value d'un élément (avec CDATA ou autre) renvoie Null. La propriété InnerText vous donnera le contenu CDATA / Text. 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") );
Sortie:
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
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 le support CDATA maintenant.
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 XPath est connu comme un text node
ou dans L'Infoset XML comme "morceaux d'éléments d'information de caractère".
Évidemment, votre outil est faux. Autres outils, comme le visualiseur XPath mettez correctement en surbrillance le texte de l'élément Name
lors de l'évaluation de cette expression XPath:
/*/Name/text()
On peut aussi é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>
Quand cela la transformation est appliquée sur le document XML fourni :
<Obj>
<Name><![CDATA[SomeText]]></Name>
</Obj>
Le résultat correct est produite:
"SomeText"
Voir si cela aide - http://www.zrinity.com/xml/xpath/
XPATH = /Obj/Nom/text()
Une suggestion serait d'avoir un autre champ du hachage md5 du cdata. Vous pouvez ensuite utiliser xpath pour interroger le md5 sans problème
<sites>
<site>
<name>Google</name>
<url><![CDATA[http://www.google.com]]></url>
<urlMD5>ed646a3334ca891fd3467db131372140</urlMD5>
</site>
</sites>
Ensuite, vous pouvez rechercher:
/sites/site[urlMD5=ed646a3334ca891fd3467db131372140]