Чтение данных из файла xml с курсами валют (ecb) для расчета - PullRequest
1 голос
/ 15 марта 2020

Я новичок здесь и не знаю точно, как начать. Если я делаю что-то не так (задавая свой вопрос), пожалуйста, не стесняйтесь, скажите мне.

Проблема, которая у меня есть, проста для вас, я думаю. Я пытаюсь прочитать данные из файла XML (ЕЦБ публикует ежедневно): курсы валют

Я делаю это, но, вероятно, самым неэффективным способом. У тебя могут быть слезы на глазах. : -)

Мой код:

while (xmlReader.Read())
        {
            if (xmlReader.Name != "")
            {

                for (int i = 0; i < xmlReader.AttributeCount; i++)
                {
                    //Prüfen ob es den Knoten/Element 'Cube' gibt
                    if (xmlReader.Name == "Cube")
                    {
                        //Falls der Knoten/Element nur 1 Attribut enthält, ist dies das Datum
                        if (xmlReader.AttributeCount == 1)
                        {
                            //Datum auslesen
                            xmlReader.MoveToAttribute("time");
                            tempDatum = DateTime.Parse(xmlReader.Value);
                        }
                        //Sind 2 Attribute im aktuellen Knoten/UnterElement, enthält dieser WährungsKürzel und Kurswert
                        if (xmlReader.AttributeCount == 2)
                        {
                            //Währung auslesen
                            xmlReader.MoveToAttribute("currency");
                            tempWaehrung = xmlReader.Value;

                            //Kurs auslesen
                            xmlReader.MoveToAttribute("rate");
                            tempKurs = double.Parse(xmlReader.Value.Replace(".", ",")); // Komma als DecimalSymbol



                            if (tempWaehrung.Equals("AUD")) AUD.Text = tempKurs.ToString();
                            if (tempWaehrung.Equals("BRL")) BRL.Text = tempKurs.ToString();
                            if (tempWaehrung.Equals("BGN")) BGN.Text = tempKurs.ToString();
                            /*and 29 other currencies...*/

                            //ausgelesene Werte zusammen in einer neuen Zeile eintragen
                            //DataRow neueZeile = dtWechselkurs.NewRow();
                            //neueZeile["Datum"] = tempDatum;
                            //neueZeile["Waehrung"] = tempWaehrung;
                            //neueZeile["Kurs"] = tempKurs;

                            //dtWechselkurs.Rows.Add(neueZeile);
                        }

                        xmlReader.MoveToNextAttribute();
                    }
                }
            }
        }
        /*foreach (DataRow row in dtWechselkurs.Rows)
        {
            foreach (var item in row.ItemArray)
            {
                //What should I do here?
            }
        }*/
    }
    protected void calculateCurrencies_Click(object sender, EventArgs e)
    {
        AUDamount.Text = (double.Parse(euro.Text) * double.Parse(AUD.Text)).ToString("0.00");
        //and 31 other currencies...
    }

У меня есть TextBox, в который пользователь вводит сумму и получает рассчитанные значения (через calcCurrencies_Click).

Пи c для курса и суммы австралийского доллара, то же самое для всех других валют

Я понимаю, что XMLReader работает. Но мне нужна какая-то структура данных, вероятно, как DataTable. Но я не знаю, как go пройти через него, чтобы избежать предложений if:

if (tempWaehrung.Equals ("AUD")) AUD.Text = tempKurs.ToString ();

Я просто хочу, чтобы tempWaehrung был именем переменной. И я анализирую от двойного до строкового и обратно и использую метки для хранения курса валюты вместо того, чтобы использовать правильную структуру данных (я не знаю, какую) для вычисления.

Так как мой Engli sh довольно плохо, надеюсь, вы, ребята, понимаете, что я пытаюсь сделать здесь. Должен быть лучший способ сделать это.

Заранее спасибо за вашу помощь, умные ребята.

Привет Альбрехт

1 Ответ

0 голосов
/ 15 марта 2020

Я думаю, вы получаете xml от api как string, тогда вы можете использовать XDocument и Parse метод для анализа вашего xml как string и используйте Linq для xml, чтобы получить валюту и курс .

1 - создайте метод, который принимает xml и возвращаем dictionary (Валюта, Курс)

private static Dictionary<string, decimal> GetCurrencyAndRateFromXml(string xml)
{
    XDocument doc = XDocument.Parse(xml);
    XNamespace xn = "http://www.ecb.int/vocabulary/2002-08-01/eurofxref";

    return doc
        .Descendants(xn + "Cube")
        .Descendants()
        .Descendants()
        .Select(x => new { currency = x.Attribute("currency").Value, rate = x.Attribute("rate").Value })
        .ToDictionary(x => x.currency, 
            value => decimal.TryParse(value.rate, NumberStyles.Number, CultureInfo.CreateSpecificCulture("en-US"), out decimal longValue) ? longValue : 0);
}

2 - Создайте метод, который принимает строковую цену ( евро. Текст ) и Ставку

private static decimal GetCalculatedPrice(string price, decimal rate)
{
    if (decimal.TryParse(price, NumberStyles.Number, CultureInfo.CreateSpecificCulture("en-US"), out decimal newPrice))
        return newPrice * rate;
    return 0;
}

3 - вызов методов в calculateCurrencies_Click, например:

protected void calculateCurrencies_Click(object sender, EventArgs e)
{
    Dictionary<string, decimal> keyValuePairs = GetCurrencyAndRateFromXml(xml);
    // keyValuePairs["AUD"] gives you rate of AUD from dictionary
    AUDamount.Text = GetCalculatedPrice(euro.Text, keyValuePairs["AUD"]).ToString("0.00"); 
    //and 31 other currencies...
} 

4 - TEST

    string xml = @"
<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=""2020-03-13"">
            <Cube currency=""USD"" rate=""1.1104""/>
            <Cube currency=""JPY"" rate=""119.11""/>
            <Cube currency=""BGN"" rate=""1.9558""/>
            <Cube currency=""CZK"" rate=""26.042""/>
            <Cube currency=""DKK"" rate=""7.4732""/>
            <Cube currency=""GBP"" rate=""0.89070""/>
            <Cube currency=""HUF"" rate=""338.88""/>
            <Cube currency=""PLN"" rate=""4.3570""/>
            <Cube currency=""RON"" rate=""4.8213""/>
            <Cube currency=""SEK"" rate=""10.8453""/>
            <Cube currency=""CHF"" rate=""1.0608""/>
            <Cube currency=""ISK"" rate=""150.00""/>
            <Cube currency=""NOK"" rate=""11.0966""/>
            <Cube currency=""HRK"" rate=""7.5630""/>
            <Cube currency=""RUB"" rate=""80.7385""/>
            <Cube currency=""TRY"" rate=""6.9850""/>
            <Cube currency=""AUD"" rate=""1.7684""/>
            <Cube currency=""BRL"" rate=""5.2042""/>
            <Cube currency=""CAD"" rate=""1.5389""/>
            <Cube currency=""CNY"" rate=""7.7587""/>
            <Cube currency=""HKD"" rate=""8.6255""/>
            <Cube currency=""IDR"" rate=""16400.61""/>
            <Cube currency=""ILS"" rate=""4.0867""/>
            <Cube currency=""INR"" rate=""81.8765""/>
            <Cube currency=""KRW"" rate=""1341.38""/>
            <Cube currency=""MXN"" rate=""23.7835""/>
            <Cube currency=""MYR"" rate=""4.7508""/>
            <Cube currency=""NZD"" rate=""1.8120""/>
            <Cube currency=""PHP"" rate=""56.453""/>
            <Cube currency=""SGD"" rate=""1.5684""/>
            <Cube currency=""THB"" rate=""35.244""/>
            <Cube currency=""ZAR"" rate=""17.9235""/>
        </Cube>
    </Cube>
</gesmes:Envelope>";

Dictionary<string, decimal> keyValuePairs = GetCurrencyAndRateFromXml(xml);
string AUDamount = GetCalculatedPrice("100", keyValuePairs["AUD"]).ToString("0.00");
Console.WriteLine(aUDamount);

5 - результат

176.84

Примечание : всегда используйте TryParse вместо Parse, потому что Parse выдает исключение, если строка недопустима число .

Пространство имен для linq до xml: System.Xml.Linq;

Я надеюсь, что это поможет вам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...