Чтение XML-элемента, содержащего массивы из ответа веб-службы

#c# #xml #webservice-client

#c# #xml #веб-сервис-клиент

Вопрос:

В настоящее время я создаю клиент веб-службы (веб-приложение C #), которое использует данные из веб-службы моего поставщика. Поскольку я не программист и впервые имею дело с веб-службой, я изучил множество руководств по использованию простых данных веб-службы. Однако я застрял, получая значение, содержащееся в массиве.

Это ответ веб-службы в формате XML, который я могу получить от SOAP-клиента, такого как SoapUI:

     <GetSiteDataResponse xmlns="http://tempuri.org/">
        <SiteDataResult 
            xmlns:a="http://schemas.datacontract.org/2004/07/KPIService"
            xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
            <a:SiteName>PMU88</a:SiteName>
            <a:SiteLocation>EcoHill</a:SiteLocation>
            <a:SiteData>
                <a:DateIntervalNode>
                    <a:Date>2019-01-01</a:Date>
                    <a:Temperature>
                        <a:TemperatureNode>
                            <a:AverageTemperature>35</a:AverageTemperature>
                            <a:Unit>C</a:Unit>
                        </a:TemperatureNode>
                    </a:Temperature>
                </a:DateIntervalNode>
                <a:DateIntervalNode>
                    <a:Date>2019-01-02</a:Date>
                    <a:Temperature>
                        <a:TemperatureNode>
                            <a:AverageTemperature>32</a:AverageTemperature>
                            <a:Unit>C</a:Unit>
                        </a:TemperatureNode>
                    </a:Temperature>
                </a:DateIntervalNode>
            </a:SiteData>
        </SiteDataResult>
    </GetSiteDataResponse>
  

Чтобы использовать данные веб-службы в веб-приложении, я добавляю ссылку на службу в веб-приложении, которая ссылается на WSDL веб-службы. Параметры результата будут отображаться в виде меток на веб-странице. Это мой код, лежащий в основе:

 public partial class SiteTemp : System.Web.UI.Page
{
    protected void btnInvoke_Click1(object sender, EventArgs e)
    {
        ServiceReference1.siteTemperatureData myWebService = new ServiceReference1.siteTemperatureDataClient();

        string username = "user1";
        string password = "mypassword";
        string siteID = "1104";

        lblSiteName.Text = myWebService.GetSiteData(username, password, siteID).SiteName;
        lblSiteLocation.Text = myWebService.GetSiteData(username, password, siteID).SiteLocation;
        lblDate1.Text = ???
        lblTemperature1.Text = ???
        lblUnit1.Text = ???
        lblDate2.Text = ???
        lblTemperature2.Text = ???
        lblUnit2.Text = ???
    }
}
  

Я могу получить значение SiteName amp; SiteLocation, но я понятия не имею, как получить значение Date, AverageTemperature amp; Unit, потому что тип элемента ‘siteData’ является массивом, и я должен пройти дальше по иерархии, чтобы получить нужные мне данные. В большинстве связанных потоков я вижу, как люди получают значение из массива buy, в моем случае также есть массив внутри массива. Любая помощь / подсказка / hint высоко ценится.

Комментарии:

1. Вы опубликовали не весь xml. Вам не хватает пространства имен ‘a’, которое необходимо.

2. Спасибо, что указали на это. Я думаю, что я пропустил это, когда копировал и вставлял, но сообщение было отредактировано, чтобы включить это.

Ответ №1:

Использование Xml Linq :

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.IO;

namespace ConsoleApplication106
{
    class Program
    {
        const string FILENAME = @"c:temptest.xml";
        static void Main(string[] args)
        {
            string xml = File.ReadAllText(FILENAME);
            XDocument doc = XDocument.Parse(xml);
            XElement root = doc.Root;
            XNamespace ns = root.GetDefaultNamespace();

            XElement siteDataResult = doc.Descendants(ns   "SiteDataResult").FirstOrDefault();
            XNamespace aNs = siteDataResult.GetNamespaceOfPrefix("a");

            Site site = new Site();
            site.siteName = (string)siteDataResult.Element(aNs   "SiteName");
            site.siteLocation  = (string)siteDataResult.Element(aNs   "SiteLocation");

            site.dict = siteDataResult.Descendants(aNs   "DateIntervalNode")
                .GroupBy(x => (DateTime)x.Element(aNs   "Date"), y => new KeyValuePair<int, string>(
                    (int)y.Descendants(aNs   "AverageTemperature").FirstOrDefault(),
                    (string)y.Descendants(aNs   "Unit").FirstOrDefault()
                    )
                )
                .ToDictionary(x => x.Key, y => y.FirstOrDefault());

        }
    }
    public class Site
    {
        public string siteName { get; set; }
        public string siteLocation { get; set; }
        public Dictionary<DateTime, KeyValuePair<int, string>> dict { get; set; }
    }

}
  

Комментарии:

1. Спасибо за ответ, но могу ли я узнать, каким должно быть мое xml-ИМЯ ФАЙЛА, если xml является ответом от веб-службы?

2. Вот почему я считываю файл в строку. Ваш ответ от веб-службы представляет собой строку, поэтому вам не нужно читать из файла. Просто используйте метод Parse для преобразования строки в XDocument.