【问题标题】:Convert AdWords XML File to C# List将 AdWords XML 文件转换为 C# 列表
【发布时间】:2019-02-23 08:47:30
【问题描述】:

这是我的 XML 文件

<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<report>
<report-name name='XML report: Account-Performance this month'/>
<date-range date='Sep 1, 2018-Sep 18, 2018'/>
    <table>
        <columns>
            <column name='impressions' display='Impressions'/>
            <column name='clicks' display='Clicks'/>
            <column name='ctr' display='CTR'/>
            <column name='conversions' display='Conversions'/>
            <column name='convRate' display='Conv. rate'/>
            <column name='costConv' display='Cost / conv.'/>
            <column name='avgCPC' display='Avg. CPC'/>
            <column name='cost' display='Cost'/>
        </columns>
        <row impressions='19534' clicks='876' ctr='4.48%' conversions='17.00' convRate='1.94%' costConv='52278824' avgCPC='1014543' cost='888740000'/>
    </table>
</report>

此文件是通过 AdWords API 生成的。我现在正在尝试将此 xml 文件转换为 c# 列表。到目前为止,这是我的方法:

// generate list out of xml
var xmlDoc = XDocument.Load(path);
var reports = xmlDoc.Elements();
foreach (var report in reports)
{
    var row = report.Element("row");
}

不幸的是 var row 为空。我做了一些调试,“报告”中只有一个报告,所以最后一部分肯定有问题。

【问题讨论】:

  • 这不验证格式良好的 xml
  • 除了缺少的Table节点,应该是Elements("row")而不是Element("row")`。表格可以有多行。
  • xml 文件由 adwords api 生成。我根本无法改变结构或任何东西。

标签: c# .net xml


【解决方案1】:

您当前的代码正在搜索report 的第一个子元素row,但您想要table 的第一个row 元素。

要获取row 元素,您必须将代码更改为:

foreach (var report in reports)
{
    var row = report.Element("table").Element("row");
}

【讨论】:

    【解决方案2】:

    你看错地方了。如果你的 XML 是正确的,它会是这样的

    string dataXML = @"<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
    <report>
        <report-name name='XML report: Account-Performance this month'/>
        <date-range date='Sep 1, 2018-Sep 18, 2018'/>
        <table>
            <columns>
                <column name='impressions' display='Impressions'/>
                <column name='clicks' display='Clicks'/>
                <column name='ctr' display='CTR'/>
                <column name='conversions' display='Conversions'/>
                <column name='convRate' display='Conv. rate'/>
                <column name='costConv' display='Cost / conv.'/>
                <column name='avgCPC' display='Avg. CPC'/>
                <column name='cost' display='Cost'/>
            </columns>
            <row impressions='19534' clicks='876' ctr='4.48%' conversions='17.00' convRate='1.94%' costConv='52278824' avgCPC='1014543' cost='888740000'/>
        </table>    
    </report>";
    

    如果您的 XML 有多个报告

    XDocument xmldx = XDocument.Parse(dataXML);
    var myReport = xmldx.Elements("report");
    foreach (var report in myReport)
    {
        var row = report.Element("table").Element("row");
    }
    

    如果您的表格有多行

    XDocument xmldx = XDocument.Parse(dataXML);
    var myReport = xmldx.Element("report");
    foreach (var table in myReport.Elements("table"))
    {
        var row = table.Element("row");
    }
    

    【讨论】:

      【解决方案3】:

      一种方法是逐步遍历元素:报表>表格>行。
      您缺少 Table 节点。

      var result = xmlDoc
          .Element("report")
          .Element("table")
          .Elements("row")
          .Select(r => new //my customObject here
          {
              impressions = (int)r.Attribute("impressions"),
              clicks = (int)r.Attribute("clicks"),
              ctr = (string)r.Attribute("ctr")
          });
      

      如果您要查找所有行,无论它们在哪里

      var result2 = xmlDoc
                  .Descendants("row")
                  .Select(r => new
                  {
                      impressions = (int)r.Attribute("impressions"),
                      clicks = (int)r.Attribute("clicks"),
                      ctr = (string)r.Attribute("ctr")
                  });
      

      请注意,即使您的 Xml 仅显示一行,我也将其处理为一个表格可以有多行。

      【讨论】:

        【解决方案4】:

        您需要指定row 元素在文档中的位置。在这种情况下,使用XPathSelectElements 既简单又健壮:

        // generate list out of xml
        var xmlDoc = XDocument.Load(path);
        var rows = xmlDoc.Root.XPathSelectElements("/report/table/row");
        foreach (var row in rows)
        {
            // ...
        }
        

        您可能需要尝试使用 XPath 查询,但我认为应该适合您。

        【讨论】:

          猜你喜欢
          • 2020-12-14
          • 1970-01-01
          • 1970-01-01
          • 2020-03-21
          • 2021-05-25
          • 1970-01-01
          • 2012-08-13
          • 2020-03-13
          • 1970-01-01
          相关资源
          最近更新 更多