#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