0

私はxmlを変数に解析しています

void myClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
         if (e.Error == null)
            {
                XElement currencyElements = XElement.Parse(e.Result);

                XNamespace gesmes = "http://www.gesmes.org/xml/2002-08-01";
                XNamespace ns = "http://www.ecb.int/vocabulary/2002-08-01/eurofxref";

                usd=Convert.ToDouble(currencyElements.Descendants(ns +"Cube")
                .Where(x=>x.Attribute("currency")!=null)             
                .Where(x => x.Attribute("currency")
                .Value == "USD")
                .Select(x => new ClassRates
                {
                    usd=Convert.ToDouble(x.Attribute("rate").Value)  
                }));


            else
            {
                textBlock1.Text = e.Error.ToString();
            }
}

これが私のクラス ClassRates です

public class ClassRates
        {
            public String curName { get; set; }
            public double curRate { get; set; }

            public double usd, jpy, bgn, czk, dkk, 
            gbp, huf, ltl, lvl, pln, ron, sek, chf, nok,
            hrk, rub, try1, aud, brl, cad, cny, hkd, idr, 
            ils, inr, krw, mxn, myr, nzd, php, sgd, thb, zar;
        }

変数usdは、計算用の解析ブロックの外では使用できません。これは、解析のためにクラスを介してアイテムを選択しているためですか? 回避策はありますか?レートを保存するために辞書/リスト/配列を実装しようとしましたが、機能しませんでした。これは、辞書を使用しようとするバージョンです

Dictionary<string, double> rates = new Dictionary<string, double>();
                String xml = e.Result;
                XElement doc = XElement.Parse(xml);
                XNamespace ns = XNamespace.Get("http://www.gesmes.org/xml/2002-08-01");
                XNamespace masterNs = XNamespace.Get("http://www.ecb.int/vocabulary/2002-08-01/eurofxref");

                doc.Element(ns.GetName("Envelope"))
                   .Element(masterNs.GetName("Cube"))
                   .Elements(masterNs.GetName("Cube"))
                   .ToList().ForEach(cube =>
                   {

                       var cubeCurrencies = cube.Descendants(masterNs.GetName("Cube"));

                       cubeCurrencies.ToList().ForEach(currency =>
                       {
                           var country = currency.Attribute("currency").Value;
                           var rate = currency.Attribute("rate").Value;

                           rates.Add(country, double.Parse(rate));
                       });

                   });

これにより、見つけることができない NullReferenceException が発生します。どんな考えでも歓迎します、

    <gesmes:Envelope xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01" xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref">
<gesmes:subject>Reference rates</gesmes:subject>
<gesmes:Sender>
  <gesmes:name>European Central Bank</gesmes:name>
</gesmes:Sender>
<Cube>
  <Cube time="2012-04-12">
    <Cube currency="USD" rate="1.3153"/>
    <Cube currency="JPY" rate="106.54"/>
    <Cube currency="BGN" rate="1.9558"/>
    <Cube currency="CZK" rate="24.803"/>
    <Cube currency="DKK" rate="7.4384"/>
    <Cube currency="GBP" rate="0.82470"/>
    <Cube currency="HUF" rate="296.90"/>
    <Cube currency="LTL" rate="3.4528"/>
    <Cube currency="LVL" rate="0.6989"/>
    <Cube currency="PLN" rate="4.1802"/>
    <Cube currency="RON" rate="4.3745"/>
    <Cube currency="SEK" rate="8.8912"/>
    <Cube currency="CHF" rate="1.2027"/>
    <Cube currency="NOK" rate="7.6100"/>
    <Cube currency="HRK" rate="7.4758"/>
    <Cube currency="RUB" rate="38.7840"/>
    <Cube currency="TRY" rate="2.3664"/>
    <Cube currency="AUD" rate="1.2645"/>
    <Cube currency="BRL" rate="2.4075"/>
    <Cube currency="CAD" rate="1.3132"/>
    <Cube currency="CNY" rate="8.2961"/>
    <Cube currency="HKD" rate="10.2128"/>
    <Cube currency="IDR" rate="12055.30"/>
    <Cube currency="ILS" rate="4.9348"/>
    <Cube currency="INR" rate="67.8550"/>
    <Cube currency="KRW" rate="1500.58"/>
    <Cube currency="MXN" rate="17.2124"/>
    <Cube currency="MYR" rate="4.0360"/>
    <Cube currency="NZD" rate="1.6001"/>
    <Cube currency="PHP" rate="56.176"/>
    <Cube currency="SGD" rate="1.6507"/>
    <Cube currency="THB" rate="40.564"/>
    <Cube currency="ZAR" rate="10.4472"/>
</Cube>
</Cube>
</gesmes:Envelope>

4

2 に答える 2

0

Linq クエリの完了時に新しいインスタンスを作成する代わりに、 のローカル インスタンスを作成しClassRateて参照します。myClient_DownloadStringCompleted

また、解析コードと同様にリファクタリングしてくださいClassRates。Linq ステートメントを分離し、通貨の種類をパラメーターとして取り、それに基づいてクエリを実行できる解析メソッドを作成します。

于 2012-04-11T21:50:48.207 に答える
0

http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractserializer%28v=vs.95%29.aspx

以下は、xml Twitter フィードを逆シリアル化する 2 つの方法の例です。また、クラスを設定し、場合によっては[DataContract]および[DataMember]属性でクラスを装飾する必要があります。

また、時間があれば、Web サービスの json を調べてください。フットプリントがはるかに小さい傾向があるため、xml よりもネットワーク経由で送信されるデータが少なくなり、簡単に逆シリアル化できます。

    void myClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
    {
        var tweets = ReadToObject(e.Result);
        var tweets2 = ReadToObject2(e.Result);
    }

    private static statuses ReadToObject(string xml)
    {
        var tweets = new statuses();
        using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
        {
            var ser = new DataContractSerializer(typeof(statuses));
            tweets = ser.ReadObject(ms) as statuses;
        }
        return tweets;

    }

    private static statuses ReadToObject2(string xml)
    {
        XmlSerializer ser = new XmlSerializer(typeof(statuses));
        var tweets = new statuses();

        using(var stringReader = new StringReader(xml))
        {
            using (var xmlReader = new XmlTextReader(stringReader))
            {
                tweets = ser.Deserialize(xmlReader) as statuses;
            }
        }
        return tweets;
    }
于 2012-04-12T18:43:57.177 に答える