web-dev-qa-db-ja.com

XPathを使用してXMLドキュメントを解析する

次のxmlがあるとしましょう(簡単な例)

<rows>
   <row>
      <name>one</name>
   </row>
   <row>
      <name>two</name>
   </row>
</rows>

XmlDocumentとXPathを使用してこれを解析しようとしています(最終的には行のリストを作成できます)。

例えば...

XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);

foreach(XmlNode row in doc.SelectNodes("//row"))
{
   string rowName = row.SelectSingleNode("//name").InnerText;
}

私のforeachループ内で、rowNameが常に「1」であるのはなぜですか?最初の反復では「1」、2番目の反復では「2」になると期待しています。

// nameは、予想どおり、行の最初のインスタンスではなく、ドキュメントの最初のインスタンスを取得するようです。結局のところ、「行」ノードでメソッドを呼び出しています。これが「ちょうどそれがどのように機能するか」である場合、誰かが私がそれを自分のニーズに合うように変更する方法を説明できますか?

ありがとうございました

15
musefan
_XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);

foreach(XmlNode row in doc.SelectNodes("//row"))
{
   var rowName = row.SelectSingleNode("name");
}
_

投稿したコードは実際に正しいですか? row.SelectNode()はXmlNodeのメンバーではないため、コンパイルエラーが発生します。

とにかく、上記の例は機能しますが、_<name>_ノード内の単一の_<row>_ノードのみを想定しているため、SelectNodes()ではなくSelectSingleNode()を使用する必要がある場合そうではありません。

他の人が示したように、_.InnerText_を使用して値だけを取得します。

16
Sir Crispalot

LINQ to XMLを使用します。コードファイルにusing System.Xml.Linq;を含め、次のコードを実行してリストを取得します

XDocument xDoc = XDocument.Load(filepath);
IEnumerable<XElement> xNames;

xNames = xDoc.Descendants("name");

名前要素のリストが表示されます。次に、それをList<string>に変換する場合は、次のようにします。

List<string> list = new List<string>();
foreach (XElement element in xNames)
{
    list.Add(element.value);
}
4
Levi Botelho

2番目のxpathは_//_で始まります。これは/descendant-or-self::node()の省略形であり、_/_で始まることがわかります。つまり、ドキュメントのルートからを検索します。 。

おそらく次のいずれかが必要です。

_var rowName = row.SelectSingleNode("name");
_

name直接の子であるrowノードを見つけるには、または

_var rowName = row.SelectSingleNode(".//name");
_

この2つ目のxpathでnameノード* anywhere undertherow _. Note the_。 `を検索すると、xpathがコンテキストノードから開始されます。

4
AakashM

相対パスを使用します。 string rowName = row.SelectSingleNode("name").InnerText;

3
Martin Honnen

問題は2番目のXPathクエリにあります。

//row

これにはグローバルスコープがあるため、どこから呼び出しても、allrow要素が選択されます。

式を次のように置き換えると機能します。

.//row
2
madd0

SelectSingleNodeを使用してから、InnerTextプロパティを使用します。

var rowName = row.SelectSingleNode("name").InnerText;
2
DaveShaw

以下を使用してください

        doc.LoadXml(xml);

            foreach(XmlNode row in doc.SelectNodes("/rows/row"))
            {
                string rowName = row.SelectSingleNode("//name").InnerText.ToString();
            }
0
Ryguy