使用xpath web api c#从xml获取数据

Posted

技术标签:

【中文标题】使用xpath web api c#从xml获取数据【英文标题】:Getting data from xml with xpath web api c# 【发布时间】:2021-11-27 12:13:43 【问题描述】:

我开始说我正在使用 C# 和 .net core 5 开发异步 Web api 应用程序。

此应用程序需要读取一个 XML 文件,给出“ok”响应(异步模式),然后将值返回给我,以便将它们插入数据库。

我写了一个这样的算法来读取节点列表,但我不知道为什么它不能正确地遍历 nodeList...

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
        
    

感谢大家的帮助!

附言

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>

【问题讨论】:

如果您在快速观看中运行doc.SelectNodes("//ITEM[@CATEGORYID=10]"),会显示什么?您还可以将input.filePath 的 XML 数据添加到问题中吗? selectNodes 显示我想要的,匹配 xpath exp 的项目。同时我把我从方法中得到的一个项目的例子放在帖子的开头 我只需要使用 foreach 从这种类型的节点中获取一些(不是全部)数据(例如 CDATA 或属性) 【参考方案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; 

【讨论】:

它绝对可以工作(即使我不得不使用 .Load 因为 .LoadXml() 给了我一个例外,不知道为什么)。唯一的问题是我不需要这个 xml 中的所有属性,而只需要某个人,如“prezzo”(CDATA 值)或 telagenzia(总是 CDATA 值) 我已经更新了答案,因此属性只包含 ID = prezzo 或 telagenzia 的值 再次抱歉,但是如果我想在获得 nodeList 后获取“ITEM”属性的值(如“LASTUPDATE”或“EXPIRED”)怎么办。附言我不需要 ATTRID 和 ATTRVALUE 之间的组合,所以我只能使用位置来获取我需要的值,对吗? 试试item.Attributes["LASTUPDATE"].InnerText

以上是关于使用xpath web api c#从xml获取数据的主要内容,如果未能解决你的问题,请参考以下文章

如何使用多个 XPath 查询在 c# 中选择单个 XML 节点

使用 XPath 查询从 XML 中获取值

如何从 C# 中的 XML Web 服务获取值?

使用xpath从xml获取子节点值

如何在 Java 中使用 XPath 从 XML 中获取特定节点?

如何使用 XPATH 从 XML 中解析和获取准确的结果