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();
3 Réponses :
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.
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?
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; } } }
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
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>
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
etruleAttrib
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.