0
votes

Liste de la valeur d'attribut spécifique au format XML à l'aide de LINQ

XDocument xdoc = new XDocument.Load(xmlPath);
List<XElement> ruleGroupList = xdoc.Descendants("Rule").ToList();

foreach (var item in ruleGroupList)
        {
            if (item.Descendants().Attributes("ruleAttrib").exist)
            {
                List<XAttribute> ruleAttriblist = item.Descendants().Attributes("ruleAttrib").ToList();
                Console.WriteLine(ruleAttriblist );
            } 
        }  
        Console.ReadLine();

4 commentaires

et qu'est-ce que vous obtenez?


impossible d'appliquer la logique conditionnelle ... qui a essayé le code dans l'instruction if est juste une instruction conditionnelle pas une syntaxe applicable, ne peut pas trouver le remplacement de "exist"


Votre XML est-il correct? Je vois que la balise non fermée et ruleAttrib n'est pas un attribut xml, c'est juste un texte dans un nœud.


Les valeurs ne sont pas des attributs. Ils sont dans l'Innertext.


3 Réponses :


0
votes
        foreach (var item in ruleGroupList)
        {

            if (item.Descendants().Attributes("ruleAttrib").Count() != 0)
            {
                List<XAttribute> ruleAttriblist  = item.Descendants().Attributes("ruleAttrib").ToList();
                
                foreach (var attrib in ruleAttriblist)
                {
                    Console.WriteLine(attrib.Value);
                }
            }

        }
        Console.ReadLine();

Works Fine... as per the expected output.

4 commentaires

impossible de trouver la règleAttrib dans le nœud principal, supprimez donc la condition if et placez-la dans la boucle interne imbriquée


Est-ce que cela compile ?? les deux boucles utilisent le même élément variable


oui .. il compile ... les deux sont dans des portées différentes


C'est intéressant. Pourriez-vous s'il vous plaît expliquer en quoi les deux ont une portée différente?



0
votes

Essayez ce qui suit qui utilise xml linq et regex:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Text.RegularExpressions;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);
            var results = doc.Descendants()
                .Where(x => (x.NodeType == XmlNodeType.Element) && (x.Elements().Count() == 0))
                .Select(x => GetAttributes((string)x))
                .Where(x => x != null)
                .Select(x => new { name = x.Groups["name"].Value, rule = x.Groups["rule"].Value })
                .ToList();
        }
        static Match GetAttributes(string innertext)
        {
            string pattern = "name=\"(?'name'[^\"]+)\"\\s+ruleAttrib=\"(?'rule'[^\"]*)";
            Match match = Regex.Match(innertext, pattern);
            if (!match.Success) match = null;

            return match;
        }
    }
}


0 commentaires

0
votes

Le ruleAttribute n'est pas un attribut, mais en fait la valeur (texte interne) de l'élément.

Vous pouvez utiliser Linq pour analyser l ' élément ( Rulexx) puis utilisez Regex pour analyser la valeur associée à ruleAttrib .

var result = ruleGroupList.Elements()
                          .Select(x=>x.Value)
                          .Where(x=> regex.IsMatch(x))
                          .Select((x,index)=>$"{index+1}.{regex.Match(x).Groups["value"].Value}");

Sortie

entrez la description de l'image ici

Si vous souhaitez utiliser le format "1.rule1Attribute", vous pouvez utiliser

List<XElement> ruleGroupList = xdoc.Root.Descendants("Rule").ToList();
var regex = new Regex("ruleAttrib='(?<value>\\S*)'");
var result = ruleGroupList.Elements()
                          .Select(x=>x.Value)
                          .Where(x=> regex.IsMatch(x))
                          .Select(x=>regex.Match(x).Groups["value"].Value);

p>


0 commentaires