1

簡単な質問がありました: 現在、XML ファイルの操作方法を学習しようとしています。質問を実行したいと考えています:

私は確かにいくつかの助けを借りることができるちょっとした問題に遭遇しました. 以下に、単純な小さな XML ファイル (Users.XML) を作成しました。

    <?xml version="1.0" encoding="utf-8" standalone="yes"?>
    <users>
      <user>
        <firstname>Might</firstname>
        <lastname>Guy</lastname>
        <username>SomeUser</username>
      </user>
      <user>
        <firstname>Bob</firstname>
        <lastname>Marley</lastname>
        <username>BobMarley</username>
      </user>       
    </users>

私がやりたいことは、そのファイルにクエリを実行して、ユーザーに関する特定の情報を取得する方法を見つけることです。姓、名、関係ありません。さて、いろいろ調べてみると、多くの人がより良い方法の1つと考えているのは次のとおりです。

string firstName;

var data = from item in doc.Descendants("users")
                   where item.Element("user").Element("username").Value == "SomeUser"
                   select new
                   {
                       fname = item.Element("user").Element("firstname").Value
                   };

//Checking to see if anything was found. I know this isn't necessary to pull
//the information. I'm just doing this so I can know to throw an error to the
//screen if none is found
    if (data.Count() > 0)
//Now pull the data. Should only be 1 hit
        foreach (var p in data)
        {
            firstName = p.ToString();
        }
    else
        MessageBox.Show("No such user found");

さて、このサンプル コードでは、ユーザーのファースト ネームが表示されます。ただし、firstName の実際の内容は「fname = Might」です。私が入れたいのは「力」だけです。もちろん、選択から「fname =」を削除すると、フィールドに名前を付けていないというエラーがスローされるため、壁にぶつかります。解決策をグーグルで検索しようとしましたが、グーグルで何を検索しているのかわからないため、あまり運がありませんでした。

だから私は3つの質問があります。情報を含むチュートリアルの方向性を示す方が簡単だとしたら、それにもわくわくします! 簡単な解決策を探しているだけでなく、タスクを完了するだけでなく XML を学習しようとしているので、なぜこのようになっているのかを理解しようとしています。

-A) このメソッドを使用して、firstName に「fname = Might」ではなく「Might」を単純に含めることは可能ですか? もしそうなら、どのように?そうでない場合、それを行う別の方法はありますか?

-B) なぜ「fname ="」が必要なのですか? これは LINQ と関係がありますか、それとも完全に別のものの一部ですか? LINQ/XML 以外に、この例はまだ他に見つけることができていないため、なぜこのようになっているのかについて、より詳細な説明を得ることができませんでした。

-C) これは、この例でやろうとしていること、つまり、あるフィールド (この場合はユーザー名) に基づいて特定の情報を XML ファイルに照会するための受け入れ可能な方法ですか? そうでない場合は、より良い方法を教えていただけますか?

4

3 に答える 3

1

使用する:

var data = from item in doc.Descendants("users")
               where item.Element("username").Value == "SomeUser"
               select new
               {
                   fname = item.Element("firstname").Value
               };

var user = data.FirstOrDefault();
var firstName = user.fname;

クエリから返された匿名オブジェクト全体を呼び出しているため、"fname=Might"を取得しています。ToStringクエリから返された匿名オブジェクトには、実際には というプロパティがありますfname

あなたのC)の質問に:このLinqToXmlでxmlファイルからデータを読み取るのは正しいアプローチです;-)

于 2013-01-21T20:20:29.843 に答える
1

ここでの問題は、p.ToString()代わりに を使用していることですp.fname。これはどうですか:

string firstName, lastName;

var data = from item in doc.Descendants("user")
           where item.Element("username").Value == "SomeUser"
           select new
           {
               fname = item.Element("firstname").Value,
               lname = item.Element("lastname").Value
           };

var p = data.FirstOrDefault();
if(p != null)
{
    firstName = p.fname;
    lastName = p.lname;
}
else
{
    MessageBox.Show("No such user found");
}

質問 B に答えるために、fname =構文を使用する必要はありません。次の代わりに、1 つの値のみが必要な場合:

   select new
   {
       fname = item.Element("firstname").Value,
   };

あなたはただ使うことができます:

   select item.Element("firstname").Value;

このselect new { key = value, key2 = value2 }構文を使用すると、匿名クラスのオブジェクトにいくつかの値を入れることができ、そこから必要な値を名前で簡単に引き出すことができます。

于 2013-01-21T20:21:17.943 に答える
1

あなたのselect文は射影です。

これは、1 つのプロパティ (属性の値を持つ fname) を持つ新しい無名オブジェクトを作成するようコンパイラに指示しています。

select new
{
  fname = item.Element("user").Element("firstname").Value
};

これは、このようなことを行うのとほぼ同じです - コンパイラが自動的にそれを行うことを除いて。

public class SomeObject
{
  public string fname { get; set; }
  public override ToString()
  {
    return "fname = " + fname;
  }
}

var data = from item in doc.Descendants("users")
                   where item.Element("user").Element("username").Value == "SomeUser"
                   select new SomeObject { fname = item.Element("user").Element("firstname").Value }

次に、foreach はすべての要素を反復処理し、オブジェクトで toString を呼び出します。

foreach (var p in data)
{
  firstName = p.ToString();
}

foreach をこれに変更すると、問題が解決します。

foreach (var p in data)
{
  firstName = p.fname;
}
于 2013-01-21T20:23:02.357 に答える