В приведенном ниже xml я хочу получить значение идентификатора тега, где тег имени имеет значение HighLevelReport%.

<RunResults xmlns="http://www.hp.com/PC/REST/API">
  <RunResult>
    <ID>17245</ID>
    <Name>output.mdb.zip</Name>
    <Type>Output Log</Type>
    <RunID>4196</RunID>
  </RunResult>
  <RunResult>
    <ID>17246</ID>
    <Name>VuserLog.zip</Name>
    <Type>Output Log</Type>
    <RunID>4196</RunID>
  </RunResult>                            
  <RunResult>
    <ID>17248</ID>
    <Name>Reports.zip</Name>
    <Type>HTML Report</Type>
    <RunID>4196</RunID>
  </RunResult>
  <RunResult>
    <ID>17249</ID>
    <Name>HighLevelReport_4196.xls</Name>
    <Type>Rich Report</Type>
    <RunID>4196</RunID>
  </RunResult>                          
</RunResults>

В настоящее время я использую набор данных, чтобы получить значение

using (DataSet reader = ds.ReadXml(xml))
{                               
    DataRow[] DR = reader.Tables[0].Select("Name like '%HighLevelReport%'");
    int testID = Convert.ToInt32(DR[0].ItemArray[0].ToString());
}

Пожалуйста, помогите мне с другим вариантом сделать то же самое.

-2
Subrata Sarkar 6 Дек 2018 в 11:48

1 ответ

Лучший ответ

Я бы не стал использовать DataSet, если в этом нет необходимости. Если вы просто имеете дело с XML, используйте XML API. Я считаю, что LINQ to XML лучше всего подходит для этого. Например:

XNamespace ns = "http://www.hp.com/PC/REST/API";
var doc = XDocument.Parse(xml);
var ids = doc.Root
             .Elements(ns + "RunResult")
             .Where(rr => ((string) rr.Element(ns + "Name"))?.StartsWith("HighLevelReport") ?? false)
             .Select(rr => (string) rr.Element(ns + "RunID"));

Вот полный пример:

using System;
using System.IO;
using System.Linq;
using System.Xml.Linq;

public class Program
{
    public static void Main()
    {
        // Alternatively, use XDocument.Load to load from a file
        string xml = File.ReadAllText("test.xml");
        var doc = XDocument.Parse(xml);
        XNamespace ns = "http://www.hp.com/PC/REST/API";
        var ids = doc.Root
            .Elements(ns + "RunResult")
            .Where(rr => ((string) rr.Element(ns + "Name"))?.StartsWith("HighLevelReport") ?? false)
            .Select(rr => (string) rr.Element(ns + "RunID"));
        foreach (var id in ids)
        {
            Console.WriteLine(id);
        }
    }
}

Предложение Where здесь обрабатывает отсутствующий элемент Name - приведение к string вернет null, и поэтому StartsWith не будет вызываться. Если элемент RunID отсутствует, вы получите нулевой элемент в вашем выводе.

3
Jon Skeet 6 Дек 2018 в 09:20