14

次のような内容のサンプルを含む Xml ファイルを作成しました。

<?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>

選択した PeriodGroup 内の Period ノードの子を読み取ることができる必要があります。それがより賢明であれば、PeriodNameはPeriodの属性になる可能性があると思います。

私はたくさんの例を見てきましたが、まったく正しいものはないようで、XmlReaderを使用するもの、XmlTextReaderを使用するもの、どちらも使用しないものなど、数十の異なる方法があるようです。Xmlファイルを読むのはこれが初めてなので、誰かが私にポインタを与えることができるかどうか尋ねると思いました. 試してみるためだけに機能するものがありますが、ぎこちなく感じます。私はVS2010とc#を使用しています。また、LINQ-Xmlを使っている方も多いと思いますので、この方法のメリット・デメリットを教えていただければ幸いです。

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);
}
4

3 に答える 3

14

次のような XPath アプローチを使用できます。

XmlNodeList xnl = doc.SelectNodes(string.Format("/Periods/PeriodGroup[@name='{0}']/Period", PG));

ただし、読みやすさのためにLINQ to XMLを好みます。

これは、指定された属性Periodに基づいてノードの子を返します。PeriodGroup nameHER

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();

結果:

<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>

クエリは非常に簡単です

from n in xml.Descendants("Periods")

element の子孫要素のコレクションを返しますPeriods。次にwhere、属性値に基づいてこのノードのコレクションをフィルタリングするために使用します。

where n.Element("PeriodGroup").Attribute("name").Value == "HER"

次に、値が次の属性をPeriodGroup持つ要素にコレクションを絞り込みます。nameHER

最後に、PeriodGroup要素を選択し、その子孫ノードを取得します

select n.Element("PeriodGroup").Descendants().Elements()

編集 (コメントを参照)

この式の結果は単なるクエリであるため、 を使用.ToList()してコレクションを列挙し、必要な値を含むオブジェクトを返します。次の例のように、要素の値を格納する匿名型を作成することもできます。

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;
}

これはnodes、クエリが実行された後のオブジェクトの外観です。

ここに画像の説明を入力

于 2013-04-12T11:43:48.953 に答える
4

このXmlDocument.SelectNodesメソッドは実際に XPath 式を受け入れるため、次のように自由に実行できます。

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>.
}

w3schoolsで XPath の詳細を学ぶことができます。

于 2013-04-12T11:39:36.040 に答える