Получение данных из xml с помощью xpath web api c#

#c# #xml #asp.net-core #xpath

Вопрос:

я начинаю говорить, что работаю над асинхронным приложением веб-api, использующим C# и .net core 5.

Это приложение должно прочитать XML-файл, выдав ответ «ок» (асинхронный режим), и вернуть мне значения, чтобы вставить их в базу данных.

Я написал подобный алгоритм для чтения списка узлов, но я не знаю, почему он неправильно перебирает список узлов…

 public class LetturaXml
{
    public List<InsertClassDTO> xmlToList(InputDTO input)
    {
        List<InsertClassDTO> list = new List<AnnuncioAutoDTO>();

        XmlDocument doc = new XmlDocument();
        doc.Load(input.filePath);

        XmlNodeList nodeList = doc.SelectNodes("//ITEM[@CATEGORYID=10]");

        foreach (XmlNode item in nodeList)
        {
            //.... tranfert into DTO, then into list, and finally insert into DB for every iteration
        }
    }
}
 

спасибо всем за помощь !

P.S.

пример xml:

 <ITEM ID="5331" CITYID="7" CATEGORYID="10" LASTUPDATE="2021-05-14" EXPIRED="0">
      <ISTAT>000</ISTAT>
      <TITLE><![CDATA[title]]></TITLE>
      <TEXT>
           <![CDATA[text]]>
      </TEXT>
      <EMAIL>@hotmail.it</EMAIL>
      <ATTRIBUTELIST>
      <ATTRIBUTE>
          <ATTRID>prezzo</ATTRID>
          <ATTRNAME></ATTRNAME>
          <ATTRVAL><![CDATA[3400]]></ATTRVAL>
      </ATTRIBUTE>
      <ATTRIBUTE>
          <ATTRID>telagenzia</ATTRID>
          <ATTRNAME></ATTRNAME>
          <ATTRVAL><![CDATA[33333333333]]></ATTRVAL>
      </ATTRIBUTE>
      <ATTRIBUTE>
          <ATTRID>contattotelefonico</ATTRID>
          <ATTRNAME></ATTRNAME>
          <ATTRVAL><![CDATA[33333333333]]></ATTRVAL>
      </ATTRIBUTE>
      <ATTRIBUTE>
          <ATTRID>2</ATTRID>
          <ATTRNAME><![CDATA[example]]></ATTRNAME>
          <ATTRVAL><![CDATA[example]]></ATTRVAL>
      </ATTRIBUTE>
      <ATTRIBUTE>
        <ATTRID>4</ATTRID>
        <ATTRNAME><![CDATA[example]]></ATTRNAME>
        <ATTRVAL><![CDATA[example]]></ATTRVAL>
      </ATTRIBUTE>
      <ATTRIBUTE>
        <ATTRID>indirizzoagenzia</ATTRID>
        <ATTRNAME></ATTRNAME>
        <ATTRVAL><![CDATA[example]]></ATTRVAL>
      </ATTRIBUTE>
      <ATTRIBUTE>
        <ATTRID>comuneagenzia</ATTRID>
        <ATTRNAME></ATTRNAME>
        <ATTRVAL><![CDATA[example]]></ATTRVAL>
      </ATTRIBUTE>
      <ATTRIBUTE>
        <ATTRID>capagenzia</ATTRID>
        <ATTRNAME></ATTRNAME>
        <ATTRVAL><![CDATA[example]]></ATTRVAL>
      </ATTRIBUTE>
      <ATTRIBUTE>
        <ATTRID>inserzionistaauto</ATTRID>
        <ATTRNAME><![CDATA[example]]></ATTRNAME>
        <ATTRVAL></ATTRVAL>
      </ATTRIBUTE>
      <ATTRIBUTE>
        <ATTRID>tipocomprovendo</ATTRID>
        <ATTRNAME><![CDATA[example]]></ATTRNAME>
        <ATTRVAL></ATTRVAL>
      </ATTRIBUTE>
      <ATTRIBUTE>
        <ATTRID>inserzionistaauto</ATTRID>
        <ATTRNAME><![CDATA[example]]></ATTRNAME>
        <ATTRVAL></ATTRVAL>
      </ATTRIBUTE>
      <ATTRIBUTE>
        <ATTRID>marca</ATTRID>
        <ATTRNAME><![CDATA[example]]></ATTRNAME>
        <ATTRVAL></ATTRVAL>
      </ATTRIBUTE>
      <ATTRIBUTE>
        <ATTRID>modello</ATTRID>
        <ATTRNAME><![CDATA[example]]></ATTRNAME>
        <ATTRVAL></ATTRVAL>
      </ATTRIBUTE>
      <ATTRIBUTE>
        <ATTRID>condizioneveicolo</ATTRID>
        <ATTRNAME><![CDATA[example]]></ATTRNAME>
        <ATTRVAL></ATTRVAL>
      </ATTRIBUTE>
      <ATTRIBUTE>
        <ATTRID>km</ATTRID>
        <ATTRNAME></ATTRNAME>
        <ATTRVAL><![CDATA[example]]></ATTRVAL>
      </ATTRIBUTE>
      <ATTRIBUTE>
        <ATTRID>immatricolazione</ATTRID>
        <ATTRNAME></ATTRNAME>
        <ATTRVAL><![CDATA[example]]></ATTRVAL>
      </ATTRIBUTE>
      <ATTRIBUTE>
        <ATTRID>alimentazione</ATTRID>
        <ATTRNAME><![CDATA[example]]></ATTRNAME>
        <ATTRVAL></ATTRVAL>
      </ATTRIBUTE>
      </ATTRIBUTELIST>
      <IMAGELIST>
          <IMGFILE><![CDATA[exampleLink.jpg]]></IMGFILE>
      </IMAGELIST>
  </ITEM> 

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

1. Если вы запускаете doc.SelectNodes("//ITEM[@CATEGORYID=10]") quick watch, что это показывает? Также можете ли вы добавить XML-данные для input.filePath ответа на вопрос?

2. в модах выбора отображается то, что я хочу, элементы, соответствующие экспрессу xpath. тем временем я помещаю пример элемента, который я получаю из метода, в начале поста

3. мне просто нужно взять некоторые (не все) данные (например, CDATA или атрибуты) из узла этого типа с помощью foreach

Ответ №1:

Надеюсь, это будет достаточной отправной точкой для вас, чтобы закончить:

 var xml = @"
<ITEM ID=""5331"" CITYID=""7"" CATEGORYID=""10"" LASTUPDATE=""2021-05-14"" EXPIRED=""0"">
        <ISTAT>000</ISTAT>
        <TITLE><![CDATA[title]]></TITLE>
        <TEXT>
            <![CDATA[text]]>
        </TEXT>
        <EMAIL>@hotmail.it</EMAIL>
        <ATTRIBUTELIST>
        <ATTRIBUTE>
            <ATTRID>prezzo</ATTRID>
            <ATTRNAME></ATTRNAME>
            <ATTRVAL><![CDATA[3400]]></ATTRVAL>
        </ATTRIBUTE>
        <ATTRIBUTE>
            <ATTRID>telagenzia</ATTRID>
            <ATTRNAME></ATTRNAME>
            <ATTRVAL><![CDATA[33333333333]]></ATTRVAL>
        </ATTRIBUTE>
        <ATTRIBUTE>
            <ATTRID>contattotelefonico</ATTRID>
            <ATTRNAME></ATTRNAME>
            <ATTRVAL><![CDATA[33333333333]]></ATTRVAL>
        </ATTRIBUTE>
        <ATTRIBUTE>
            <ATTRID>2</ATTRID>
            <ATTRNAME><![CDATA[example]]></ATTRNAME>
            <ATTRVAL><![CDATA[example]]></ATTRVAL>
        </ATTRIBUTE>
        </ATTRIBUTELIST>
        <IMAGELIST>
            <IMGFILE><![CDATA[exampleLink.jpg]]></IMGFILE>
        </IMAGELIST>
    </ITEM>";

var list = new List<InsertClassDTO>();

XmlDocument doc = new XmlDocument();
doc.LoadXml(xml); // LoadXml() is used to load XML from a string. Use Load() to load XML from a file path)

XmlNodeList nodeList = doc.SelectNodes("//ITEM[@CATEGORYID=10]");

foreach (XmlNode item in nodeList)
{
    //.... tranfert into DTO, then into list, and finally insert into DB for every iteration
    var attirbutes = new List<Attirbute>();

    foreach (XmlNode x in item["ATTRIBUTELIST"].SelectNodes("ATTRIBUTE/ATTRID[text() = 'prezzo'] | ATTRIBUTE/ATTRID[text() = 'telagenzia']"))
    {
        attirbutes.Add(new Attirbute()
        {
            Id = x.ParentNode["ATTRID"].InnerText,
            Value = x.ParentNode["ATTRVAL"].InnerText,
        });
    }

    list.Add(new InsertClassDTO()
    {
        Email = item["EMAIL"].InnerText,
        Attributes = attirbutes
    });
}
 

Вам также понадобятся некоторые модели:

 public class InsertClassDTO
{
    public string Email { get; set; }
    public List<Attirbute> Attributes { get; set; }


}
public class Attirbute
{
    public string Id { get; set; }
    public string Value { get; set; }
}
 

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

1. это определенно сработает (даже если бы мне пришлось использовать . Загрузите, потому что .loadXML() дает мне исключение, не знаю, почему). Единственная проблема в том, что мне нужны не все атрибуты из этого xml, а только кто-то, например «prezzo»(значение CDATA) или telagenzia(всегда значение CDATA).

2. Я обновил ответ, чтобы атрибуты включали только значения, где ID = prezzo или telagenzia

3. еще раз извините, но как насчет того, чтобы я хотел получить значение атрибутов «ЭЛЕМЕНТА» (например, «ДАТА ПОСЛЕДНЕГО» или «ИСТЕК СРОК действия») после того, как я получил список узлов. P.S. мне не нужна комбинация между ATTRID и ATTRVALUE, поэтому я могу получить нужное значение только с помощью позиции, это правильно?

4. пробовать item.Attributes["LASTUPDATE"].InnerText