次の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は、予想どおり、行の最初のインスタンスではなく、ドキュメントの最初のインスタンスを取得するようです。結局のところ、「行」ノードでメソッドを呼び出しています。これが「ちょうどそれがどのように機能するか」である場合、誰かが私がそれを自分のニーズに合うように変更する方法を説明できますか?
ありがとうございました
_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
_を使用して値だけを取得します。
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);
}
2番目のxpathは_//
_で始まります。これは/descendant-or-self::node()
の省略形であり、_/
_で始まることがわかります。つまり、ドキュメントのルートからを検索します。 。
おそらく次のいずれかが必要です。
_var rowName = row.SelectSingleNode("name");
_
name
の直接の子であるrow
ノードを見つけるには、または
_var rowName = row.SelectSingleNode(".//name");
_
この2つ目のxpathでname
ノード* anywhere underthe
row _. Note the
_。 `を検索すると、xpathがコンテキストノードから開始されます。
相対パスを使用します。 string rowName = row.SelectSingleNode("name").InnerText;
。
問題は2番目のXPathクエリにあります。
//row
これにはグローバルスコープがあるため、どこから呼び出しても、allrow
要素が選択されます。
式を次のように置き換えると機能します。
.//row
SelectSingleNodeを使用してから、InnerTextプロパティを使用します。
var rowName = row.SelectSingleNode("name").InnerText;
以下を使用してください
doc.LoadXml(xml);
foreach(XmlNode row in doc.SelectNodes("/rows/row"))
{
string rowName = row.SelectSingleNode("//name").InnerText.ToString();
}