9

設定

私はこれを私のMain()機能に持っています。

List<Token> tokens = new List<Token>();
string path = @"\(some directories)\tokens.xml";
XDocument doc = XDocument.Load(path);

私はいくつかのプロパティを持つこのクラスを持っています。

public partial class Token
{
    public Token()
    {
        SetURLs = new List<string>();
        SetNames = new List<string>();
    }

    public string Name { get; set; }
    public List<string> SetURLs { get; set; }
    public List<string> SetNames { get; set; }
    public string Color { get; set; }
    public string PT { get; set; }
    public string Text { get; set; }
}

この XML ファイルがあります。ここにスニペットがあります。

<?xml version="1.0" encoding="UTF-8"?> //EDIT3
<card_database version="2">            //EDIT3
    <cards>
        .
        .
        .
        <card>
            <name>Griffin</name>
            <set picURL="http://magiccards.info/extras/token/duel-decks-ajani-vs-nicol-bolas/griffin.jpg" picURLHq="" picURLSt="">DDH</set>
            <color>w</color>
            <manacost></manacost>
            <type>Token</type>
            <pt>2/2</pt>
            <tablerow>0</tablerow>
            <text>Flying</text>
            <token>1</token>
        </card>
        <card>
            <name>Rat</name>
            <set picURL="http://magiccards.info/extras/token/shadowmoor/rat.jpg" picURLHq="" picURLSt="">SHM</set>
            <set picURL="http://magiccards.info/extras/token/gatecrash/rat.jpg" picURLHq="" picURLSt="">GTC</set>
            <color>b</color>
            <manacost></manacost>
            <type>Token</type>
            <pt>1/1</pt>
            <tablerow>0</tablerow>
            <text></text>
            <token>1</token>
        </card>
        .
        .
        .
    </cards>
</card_database> //EDIT3

ご覧のとおり、ルート要素<card>には多くの要素があります。<cards>さらに、それぞれ<card>が多くの<set>要素を持つことができます。私はそれに応じてクラスを作りました。

問題

<card>一度に 1 つずつ調べて、各プロパティに適切な値を割り当てるにはどうすればよいですか?

私が試したこと

<name>それぞれのすべての要素を含むリストを作成しました<card>。次に、このリストを調べて、TokenクラスのNameプロパティの新しいインスタンスに名前を割り当てます。次に、tokens新しいインスタンスごとにリストを作成します。

List<string> names = new List<string>();
names = doc.Descendants("card").Elements("name").Select(r => r.Value).ToList();
int amount = doc.Descendants("card").Count();

for(int i = 0; i < amount; i++)
{
    Token token = new Token();

    token.Name = name[i];

    .
    .
    .

    tokens.Add(token);
}

その後、他のすべての必要な要素を含むリストをさらに作成し、同じプロセスを実行できると思いますが、もっとエレガントな方法が必要ですよね?

編集

私も別の質問から連載を試みました。tokenしかし、何らかの理由で、コンソール (token.Name など)から何かを書き込もうとしたときに、何も書き込まれませんでした。

XmlSerializer serializer = new XmlSerializer(typeof(Token));
using (StringReader reader = new StringReader(path))
{
    Token token = (Token)(serializer.Deserialize(reader));
}

おそらく単に間違った実装です。その場合、誰かが私が投稿したものを使用して、正しい実装を見せてもらえますか? また、これにより、2 つのプロパティに 1 つまたは複数の値が与えられると思いListますよね?

編集

助けてくれてありがとう。

EDIT2

答え

シリアライゼーションをいじって失敗し、さらに検索した後、機能する実装を作成しました。

foreach (var card in doc.Descendants("card"))
{
    Token token = new Token();

    token.Name = card.Element("name").Value.ToString();
    foreach (var set in card.Elements("set"))
    {
        token.SetURLs.Add(set.Attribute("picURL").Value.ToString());
        token.SetNames.Add(set.Value.ToString());
    }
    token.Color = card.Element("color").Value.ToString();
    token.PT = card.Element("pt").Value.ToString();
    token.Text = card.Element("text").Value.ToString();

    tokens.Add(token);
}

私が最初に考えていた数よりもはるかに優れListsています。シリアライゼーションほど簡潔ではありません。しかし、それは私が必要とすることをします。

助けてくれてありがとう。

EDIT4

これだけ多くの編集が許可されているのか、エチケットに違反しているのかは不明です。将来の読者のためにこの編集をしたかっただけです。

「An Answer」セクションの下のものは私の問題を解決しますが、Dave によって以下に投稿された XML Serialization ははるかに優れています。より柔軟で、再利用/変更が容易です。そのため、状況により多くのメリットがあるソリューションを選択してください。

4

3 に答える 3

3

Linq to Xml を使用すると、

string path = @"~/tokens.xml";
var doc = XDocument.Load(Server.MapPath(Url.Content(path)));


var cards = doc.Descendants("card")
    .Select(x =>
        new Token
        {
            Name = x.Element("name").Value,
            SetURLs = x.Elements("set").Select(y => y.Attribute("picURL").Value)
                                       .ToList(),
            SetNames = x.Elements("set").Select(y => y.Value).ToList(),
            Color = x.Element("color").Value,
            PT = x.Element("pt").Value,
            Text = x.Element("text").Value
        }).ToList();

お役に立てれば。

于 2013-04-22T20:46:18.660 に答える
0

この投稿をチェックしてください:

XPath と *.csproj

ただし、以下を使用して、匿名型を具体的なクラスに変換してください。始めるには十分なはずです。

            XDocument xDoc = /* populate from somewhere */

            XNamespace nsPlaceHolder = XNamespace.Get("http://schemas.microsoft.com/developer/msbuild/2003");

  XNamespace ns = string.Empty;


            var list1 = from list in xDoc.Descendants(ns + "cards")
                        from item in list.Elements(ns + "card")
                        /* where item.Element(ns + "card") != null */
                    select new
                       {

                           PicURL = item.Attribute("picURL").Value,
                           MyName = (item.Element(ns + "name") == null) ? string.Empty : item.Element(ns + "name").Value
                       };


            foreach (var v in list1)
            {
                Console.WriteLine(v.ToString());
            }
于 2013-04-22T17:43:46.560 に答える