1

現在のXMLタグのインデックスを取得するにはどうすればよいですか?

例:

<User>
  <Contact>
    <Name>Lucas</Name>
  </Contact>
  <Contact>
    <Name>Andre</Name>
  </Contact>
    ...
</User>

私は以下のコードを試しています

    foreach (var element2 in doc2.Root.Descendants())
    {
        String name = element.Name.LocalName;
        String value = element.Value;
    }

<Contact>最初のタグを読んでいるのか、2番目のタグを読んでいるのか、3番目のタグを読んでいるのかを知りたい...

4

6 に答える 6

5

Selectの適切なオーバーロードを使用すると、コレクションを列挙するときにインデックスが生成されます。

var userContacts = doc2.Root
                       .Descendants()
                       .Where(element => element.Name == "Contact")
                       .Select((c, i) => new {Contact = c, Index = i});

foreach(var indexedContact in userContacts)
{
     // indexedContact.Contact
     // indexedContact.Index                 
}

注:.Whereを追加しました。これは、.Descendantsが再帰するためです。

于 2012-08-14T15:00:26.353 に答える
2

ステートメントを使用するforと、常にインデックスを知ることができます。Descendants()forステートメントで使用できると仮定しています。

他の可能性は、の外にカウント変数を作成することforeachです。

int count = 0
foreach (var element2 in doc2.Root.Descendants())
{
    String name = element.Name.LocalName;
    String value = element.Value;

    count++;
}
于 2012-08-14T14:54:43.790 に答える
1

変数をカウンターとして使用し、結果を配列に入れます。ここでの問題は、事前に配列のサイズを知る必要があるということです。

int i = 0;
foreach (var element in doc2.Root.Descendants()) {
     name[i] = element.Name.LocalName;
     value[i] = element.Value;
     i++;
} 

を使用すると、List<T>この問題は発生しません

var list = new List<KeyValuePair<string,string>>();
foreach (var element in doc2.Root.Descendants()) {
     list.Append(new KeyValuePair(element.Name.LocalName, element.Value));
} 
于 2012-08-14T14:57:25.270 に答える
1

foreachループを通常のforループに置き換えます。

for (int i = 0; i < doc2.Root.Descendants().Count(); i++)
{
    String name = doc2.Root.Descendants()[i].Name.LocalName;
    String value = doc2.Root.Descendants()[i].Value;
}

次に、を使用iして、1番目、2番目、3番目などのタグを読んでいるかどうかを確認します。

外部カウンターを使用せずにforeach列挙子のインデックスを取得する方法はありません。

ループの反復ごとにDescendantsメソッドを2回処理する必要があるため、これも効率の問題を引き起こします。したがって、forループの外側に子孫を表すリストを保持し、次のように使用することをお勧めします。

var desecendants = doc2.Root.Descendants().ToList();
for (int i = 0; i < descendants.Count; i++)
{
    String name = descendants[i].Name.LocalName;
    String value = descendants[i].Value;
}
于 2012-08-14T14:54:05.910 に答える
1

foreachを使用することはできないと思います。代わりに、通常のforループを使用してみてください。

于 2012-08-14T14:54:23.133 に答える
0

(以前のソリューションで指摘されているように)カウンターなしで現在のノードの位置を取得するには、現在のXmlElementのXPathを構築する関数を作成する必要があります。これを行う唯一の方法は、親ノードと前の兄弟を使用して、ノードからドキュメントをトラバースすることです。そうすれば、ドキュメントからノードにアクセスするための正確なXPathを構築できます。これがここから取ったサンプルです

   public static string GetXPath_UsingPreviousSiblings(this XmlElement element)
    {
        string path = "/" + element.Name;

        XmlElement parentElement = element.ParentNode as XmlElement;
        if (parentElement != null)
        {
            // Gets the position within the parent element, based on previous siblings of the same name.
            // However, this position is irrelevant if the element is unique under its parent:
            XPathNavigator navigator = parentElement.CreateNavigator();
            int count = Convert.ToInt32(navigator.Evaluate("count(" + element.Name + ")"));
            if (count > 1) // There's more than 1 element with the same name
            {
                int position = 1;
                XmlElement previousSibling = element.PreviousSibling as XmlElement;
                while (previousSibling != null)
                {
                    if (previousSibling.Name == element.Name)
                        position++;

                    previousSibling = previousSibling.PreviousSibling as XmlElement;
                }

                path = path + "[" + position + "]";
            }

            // Climbing up to the parent elements:
            path = parentElement.GetXPath_UsingPreviousSiblings() + path;
        }

        return path;
    }

それが本当に必要なものであると仮定すると、ドキュメントサイズによっては、リソースを大量に消費する可能性があります。インデックスのみが必要な場合は、他の方法のいずれかを使用することをお勧めします。

于 2012-08-14T15:02:09.980 に答える