web-dev-qa-db-fra.com

Quelle est l'utilisation correcte de XmlNode.SelectSingleNode (string xpath) en C #?

Je ne parviens pas à gérer certains fichiers XML (qui se trouvent à la fin de ce post).

J'ai écrit le code suivant afin d'obtenir les données Job_Id relatives à un modèle Job_Name donné dont le propriétaire Job_Owner est l'utilisateur qui exécute le probram:

List<String> jobID = new List<String>();
XmlNodeList nodes = xml.SelectNodes("//Job");
foreach (XmlNode node in nodes)
{
    innerNode = node.SelectSingleNode("//Job_Owner"); // SelectSingleNode here always selects the same node, but I thought it should be relative to node, not to nodes
    if (!innerNode.InnerText.Contains(Environment.UserName))
    {
        continue;
    }
    innerNode = node.SelectSingleNode("//Job_Name");
    if (!Regex.IsMatch(innerNode.InnerText, jobNamePattern, RegexOptions.Compiled))
    {
        continue;
    }
    innerNode = node.SelectSingleNode("//Job_Id");
    jobID.Add(innerNode.InnerText);
}

Je m'attendrais à ce que node.SelectSingleNode("//Job_Name") recherche une balise nommée Job_Name uniquement sous le code xml représenté par node.

Ce n’est pas ce qui semble se produire, car il renvoie toujours le même noeud, peu importe l’étape de la variable foreach (c’est-à-dire la variable node sélectionnée dans les modifications nodes, mais la node.SelectSingleNode("//Job_Name") renvoie toujours le même contenu).

Quel est le problème avec ce code?

Merci d'avance!

-

Le fichier XML ressemble à ceci:

<Data>
    <Job>
        <Job_Id>58282.minerva</Job_Id>
        <Job_Name>sb_net4_L20_sType1</Job_Name>
        <Job_Owner>mgirardis@minerva</Job_Owner>
        <!--more tags-->
    </Job>
    <Job>
        <!--etc etc etc-->
    </Job>
    <!--etc etc etc-->
</Data>
16
Girardi

C'est parce que vous utilisez la syntaxe '//' dans XPath. Cette syntaxe spécifique sélectionne le premier nœud du document nommé. Essayez de regarder https://www.w3schools.com/xml/xpath_syntax.asp pour obtenir des informations sur la syntaxe XPath.

Si vous recherchez des nœuds enfants, essayez simplement d'utiliser le nom du nœud (IE: "Job_Owner" au lieu de "// Job_Owner").

21
Infernex87

Infernex87 a raison de dire que Job_Owner est simple et efficace dans ce cas. Cependant, si ce n'était pas un enfant direct, vous pourriez faire:

.//Job_Owner

Comme pour les répertoires, . est le nœud actuel. Il trouve donc les descendants du nœud actuel plutôt que la racine du document.

16
Matthew Flaschen

Infernex87 a cloué la raison. En passant par votre XML, je suppose que la route LINQ pourrait être une bonne option pour vous. Si vous souhaitez commencer, le blog de Scott Gu est une excellente ressource.

1
Arun