Получение содержимого элемента XML с использованием XDoc в C#
Я использую API xignite для получения данных обмена валюты в реальном времени. Когда я использую мою строку запроса:
http://globalcurrencies.xignite.com/xGlobalCurrencies.xml/GetRealTimeRate?Symbol=GBPEUR&_token=[mytoken]
Я получаю следующее:
<Rate xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.xignite.com/services/">
<Outcome>Success</Outcome>
<Identity>Request</Identity>
<Delay>0.0218855</Delay>
<BaseCurrency>USD</BaseCurrency>
<QuoteCurrency>EUR</QuoteCurrency>
<Symbol>USDEUR</Symbol>
<Date>08/24/2016</Date>
<Time>3:23:34 PM</Time>
<QuoteType>Calculated</QuoteType>
<Bid>0.889126</Bid>
<Mid>0.88915</Mid>
<Ask>0.889173</Ask>
<Spread>4.74352E-05</Spread>
<Text>
1 United States dollar = 0.88915 European Union euro
</Text>
<Source>Rate calculated from EUR:USD</Source>
</Rate>
Я пытаюсь получить доступ к содержимому Mid
элемент и до сих пор я делаю это
var xDoc = XDocument.Load(
"http://globalcurrencies.xignite.com/xGlobalCurrencies.xml/GetRealTimeRate?Symbol="
+ "GBP" + "EUR" + "&_token=[MyToken]");
string s = (string)xDoc.Root.Element("Mid");
output.Text = s;
xDoc
переменная возвращается с XML, который я показал ранее, но когда я пытаюсь получить содержимое Mid
элемент, string s
является null
, Как мне получить доступ к содержимому элемента Mid
используя XDoc?
2 ответа
Полное имя в XML состоит из двух частей: пространства имен и локального имени. В вашем XML ваше локальное имя Mid
, но ваше пространство имен не пустое: оно http://www.xignite.com/services/
, как обозначено объявлением пространства имен по умолчанию xmlns="..."
в корневом элементе.
Если вы примете это во внимание, вы получите результат:
XNamespace ns = "http://www.xignite.com/services/";
var mid = (decimal)xDoc.Root.Element(ns + "Mid");
Я использую Linq для XML, вот пример
XNamespace ns = "http://www.xignite.com/services/";
XDocument xdoc = XDocument.Load(xmlPath);
var rateMids = (from obj in xdoc.Descendants(ns + "Rate")
select new Rate
(
obj.Attribute("Outcome").Value,
obj.Attribute("Identity").Value,
(decimal)obj.Attribute("Delay").Value,
obj.Attribute("BaseCurrency").Value,
obj.Attribute("QuoteCurrency").Value,
obj.Attribute("Symbol").Value,
DateTime.Parse(obj.Attribute("Date").Value),
obj.Attribute("Time").Value.ToString("hh:mm:ss tt", CultureInfo.CurrentCulture),
obj.Attribute("QuoteType").Value,
(decimal)obj.Attribute("Bid").Value,
(decimal)obj.Attribute("Mid").Value,
(decimal)obj.Attribute("Ask").Value,
Convert.ToInt32(obj.Attribute("Spread").Value),
Convert.ToInt32(obj.Attribute("Text").Value)
)
).ToArray();
myObjects будет содержать массив MyObjects из файла XML.
Изменить: так как вы обновили свой вопрос с XML, я думаю, что вы пропускаете только пространство имен в запросе (ns в моем запросе), пожалуйста, посмотрите на ответ Чарльза Мэгера
Мой ответ - другой подход. Вы сохраняете объект Rate и используете его без необходимости повторного чтения XML (вам нужно определить Rate в классе). Будьте осторожны с преобразованиями значений, которые я сделал, вам нужно будет соответствовать вашему классу:)