J'ai créé un fichier XML avec un exemple de contenu, comme suit:
<?xml version="1.0" encoding="utf-8" ?>
<Periods>
<PeriodGroup name="HER">
<Period>
<PeriodName>Prehistoric</PeriodName>
<StartDate>-500000</StartDate>
<EndDate>43</EndDate>
</Period>
<Period>
<PeriodName>Iron Age</PeriodName>
<StartDate>-800</StartDate>
<EndDate>43</EndDate>
</Period>
<Period>
<PeriodName>Roman</PeriodName>
<StartDate>43</StartDate>
<EndDate>410</EndDate>
</Period>
</PeriodGroup>
<PeriodGroup name="CAFG">
<Period>
<PeriodName>Prehistoric</PeriodName>
<StartDate>-500000</StartDate>
<EndDate>43</EndDate>
</Period>
<Period>
<PeriodName>Roman</PeriodName>
<StartDate>43</StartDate>
<EndDate>410</EndDate>
</Period>
<Period>
<PeriodName>Anglo-Saxon</PeriodName>
<StartDate>410</StartDate>
<EndDate>800</EndDate>
</Period>
</PeriodGroup>
</Periods>
Je dois être capable de lire les enfants du noeud Période dans un groupe de périodes sélectionné. Je suppose que PeriodName pourrait être un attribut de Period si cela est plus judicieux.
J'ai examiné une foule d'exemples, mais aucun ne semble être tout à fait correct et il semble y avoir des dizaines de méthodes différentes, certaines utilisant XmlReader, d'autres XmlTextReader et d'autres non. Comme c'est la première fois que je lis un fichier XML, j'ai pensé demander à quelqu'un si quelqu'un pouvait me donner un pointeur. Il y a quelque chose qui fonctionne juste pour essayer, mais ça semble maladroit. J'utilise VS2010 et c #. En outre, je constate que de nombreuses personnes utilisent LINQ-Xml. J'apprécierais donc les avantages et les inconvénients de cette méthode.
string PG = "HER";
XmlDocument doc = new XmlDocument();
doc.Load(Server.MapPath("./Xml/XmlFile.xml"));
string text = string.Empty;
XmlNodeList xnl = doc.SelectNodes("/Periods/PeriodGroup");
foreach (XmlNode node in xnl)
{
text = node.Attributes["name"].InnerText;
if (text == PG)
{
XmlNodeList xnl2 = doc.SelectNodes("/Periods/PeriodGroup/Period");
foreach (XmlNode node2 in xnl2)
{
text = text + "<br>" + node2["PeriodName"].InnerText;
text = text + "<br>" + node2["StartDate"].InnerText;
text = text + "<br>" + node2["EndDate"].InnerText;
}
}
Response.Write(text);
}
Vous pouvez utiliser une approche XPath comme ceci:
XmlNodeList xnl = doc.SelectNodes(string.Format("/Periods/PeriodGroup[@name='{0}']/Period", PG));
Bien que préfère LINQ to XML pour sa lisibilité.
Ceci retournera les enfants du noeud Period
en fonction de l'attribut PeriodGroup
name
fourni, par exemple. HER
:
XDocument xml = XDocument.Load(HttpContext.Current.Server.MapPath(FileLoc));
var nodes = (from n in xml.Descendants("Periods")
where n.Element("PeriodGroup").Attribute("name").Value == "HER"
select n.Element("PeriodGroup").Descendants().Elements()).ToList();
Résultats:
<PeriodName>Prehistoric</PeriodName>
<StartDate>-500000</StartDate>
<EndDate>43</EndDate>
<PeriodName>Iron Age</PeriodName>
<StartDate>-800</StartDate>
<EndDate>43</EndDate>
<PeriodName>Roman</PeriodName>
<StartDate>43</StartDate>
<EndDate>410</EndDate>
La requête est assez simple
from n in xml.Descendants("Periods")
Renverra une collection d'éléments descendants pour l'élément Periods
. Nous utilisons ensuite where
pour filtrer cette collection de nœuds en fonction de la valeur de l'attribut:
where n.Element("PeriodGroup").Attribute("name").Value == "HER"
Filtre ensuite la collection en éléments PeriodGroup
qui ont un attribut name
avec une valeur de HER
Enfin, nous sélectionnons l'élément PeriodGroup
et obtenons ses nœuds descendants
select n.Element("PeriodGroup").Descendants().Elements()
EDIT (Voir les commentaires)
Le résultat de cette expression n'étant qu'une requête, nous utilisons .ToList()
pour énumérer la collection et renvoyer un objet contenant les valeurs nécessaires. Vous pouvez également créer des types anonymes pour stocker les valeurs d'élément, par exemple:
var nodes = (from n in xml.Descendants("Period").
Where(r => r.Parent.Attribute("name").Value == "HER")
select new
{
PeriodName = (string)n.Element("PeriodName").Value,
StartDate = (string)n.Element("StartDate").Value,
EndDate = (string)n.Element("EndDate").Value
}).ToList();
//Crude demonstration of how you can reference each specific element in the result
//I would recommend using a stringbuilder here..
foreach (var n in nodes)
{
text += "<br>" + n.PeriodName;
text += "<br>" + n.StartDate;
text += "<br>" + n.EndDate;
}
Voici à quoi ressemblera l'objet nodes
après l'exécution de la requête:
Puisque la méthode XmlDocument.SelectNodes
accepte en réalité une expression XPath, vous êtes libre de procéder comme suit:
XmlNodeList xnl = doc.SelectNodes("/Periods/PeriodGroup[@name='" + PG + "']/Period");
foreach (XmlNode node in xnl) {
// Every node here is a <Period> child of the relevant <PeriodGroup>.
}
Vous pouvez en apprendre plus sur XPath à l’adresse w3schools .
aller à travers cela
public static void XMLNodeCheck(XmlNode xmlNode)
{
if (xmlNode.HasChildNodes)
{
foreach (XmlNode node in xmlNode)
{
if (node.HasChildNodes)
{
Console.WriteLine(node.Name);
if (node.Attributes.Count!=0)
{
foreach (XmlAttribute att in node.Attributes)
{
Console.WriteLine("----------" + att.Name + "----------" + att.Value);
}
}
XMLNodeCheck(node);//recursive function
}
else
{
if (!node.Equals(XmlNodeType.Element))
{
Console.WriteLine(node.InnerText);
}
}
}
}
}