选择XML中可能存在或不存在的子元素列表

时间:2010-12-06 17:25:56

标签: c# .net linq-to-xml subquery

我所拥有的是从Web服务收到的XML,它代表了一系列问题。问题按类型细分,表明它们应如何在网络上显示。例如:

<step id="109025">
  <stepinf enabled="Yes" errors="0" id="First Name" mandatory="Yes" name="sti_115511" type="FIL">
    <field_label>First Name</field_label>
    <screen_value></screen_value>
  </stepinf>
  <stepinf enabled="Yes" errors="0" id="Last Name" mandatory="Yes" name="sti_115513" type="FIL">
    <field_label>Last Name</field_label>
    <screen_value></screen_value>
  </stepinf>
  <stepinf enabled="Yes" errors="0" id="State" mandatory="Yes" name="sti_109257" type="STE">
    <field_label>State</field_label>
    <screen_value></screen_value>
    <options_list>
      <option label="AK">AK - Alaska</option>
      <option label="AL">AL - Alabama</option>
      <option label="AR">AR - Arkansas</option>
      <option label="AS">AS - American Samoa (Terr.)</option>
      <option label="AZ">AZ - Arizona</option>
      ...
    </options_list>
  </stepinf>
</step>

“STE”类型表示它将在网络上显示为选择框。

我正在填充List&lt;&gt;通过执行以下操作创建的自定义类型:

var stepinfList = (from stepinf in xdoc.Descendants("stepinf")
    select new Question
    {
       TextID = stepinf.Attribute("id").Value,
       Type = stepinf.Attribute("type").Value,
       Name = stepinf.Attribute("name").Value,
       Label = stepinf.Element("field_label").Value,
       Required = stepinf.Attribute("mandatory").Value,
       ErrorCount = int.Parse(stepinf.Attribute("errors").Value)
    }).ToList();

我迷路的地方是,我不知道如何将选项子元素放入我的结果中。我尝试在名为Options的Question类型中创建一个属性,我将其定义为IDictionary,然后在我的LINQ查询和ToDictionary扩展中使用子选择。

Options = (from option in xdoc.Element("options_list").Elements("option")
    select option)
    .ToDictionary(x => x.Attribute("label").Value, x => x.Value)

这不起作用,因为我认为它对没有子option_list元素的stepinf记录进行了轰炸。无论如何,当我运行页面时,我在LINQ语句中得到“对象引用没有设置为对象的实例”。

我担心这超出了我目前的LINQ技能,所以任何帮助都会受到高度赞赏。

1 个答案:

答案 0 :(得分:0)

  

这不起作用,因为我认为它是炸弹   在stepinf记录中没有   有子option_list元素。

您的评估是正确的,因此您需要在查询之前检查option_list是否存在。检查它是否为null并返回字典或相应地返回null。

试试这个:

Options = stepinf.Element("options_list") == null ? null :
              stepinf.Element("options_list").Elements("option")
                     .ToDictionary(x => x.Attribute("label").Value, x => x.Value)