【问题标题】:Linq to XML without knowing how many descendants there areLinq to XML 不知道有多少后代
【发布时间】:2012-04-10 00:07:56
【问题描述】:

我正在查看一个如下所示的 XML 文件:

<test>
   <vehiclenumber>123</vehiclenumber>
   <form>
     <form_id>1</form_id>
     <datafield>
         <fieldnumber>1</fieldnumber>
         <data>
            <datawords>
               <datatext1>1234</datatext1>
               <mc2>656865</mc2>
            </datawords>
         </data>
      </datafield>
   </form>
</test>

目前我有以下代码:

IEnumerable<XElement> elements = documentXDoc.Descendants("test");

            _fuelReceipts.AddRange(elements
                .Select(receipt => new Receipt()
                {
                    vehicle_number = receipt.Element("vehiclenumber") == null ? "" : receipt.Element("vehiclenumber").Value,
                    field = receipt.Descendants("datafield")
                    .Select(x => new Field()
                    {
                        field_number = x.Element("fieldnumber") == null ? "" : x.Element("fieldnumber").Value,
                        event_data = x.Descendants("data")
                        .Select(y => new FieldData()
                        {
                            event_data = y.Value
                        }).ToList()
                    }).ToList()
                }));
        }

这里的问题是,对于&lt;data&gt;,我不知道那里会有多少后代,也不知道他们会被称为什么。有没有办法在不知道这些信息的情况下单独解析这些信息?现在,我会得到类似 1234656865 的东西,而实际上我想要一个对象中的 1234 和同一对象中的单独对象中的 656865。

【问题讨论】:

    标签: c# linq-to-xml


    【解决方案1】:

    将您的内部“数据”选择更改为:

    event_data = x.Descendants("data").Descendants().Where(d => !d.HasElements).Select(y => y.Value).ToList()
    

    这将给出一个包含两个元素的 string 列表:1234 和 656865。您可以使用 String.Join() 方法轻松地将其连接到一个字符串:

    event_data = String.Join(" ", x.Descendants("data").Descendants().Where(d => !d.HasElements).Select(y => y.Value).ToList())
    

    【讨论】:

    • 当我这样做时,我在最后的 ToList() 上得到一个错误。它正在尝试将 generic.list 转换为我的业务对象。现在业务对象只是 public string event_data { get;放; },这应该是什么工作?
    • 我编辑了我的答案。 event_data 应该是 List&lt;string&gt;IEnumerable&lt;string&gt;。如果您只想要一个带有空格作为分隔符的字符串,请使用第二个示例,String.Join()
    【解决方案2】:

    我假设 XML 后代的名称是有意义的。此代码将它们放入字典中,同时将它们提取到 Field 对象中。

    void Main()
    {
        string input = "<test><vehiclenumber>123</vehiclenumber><form><form_id>1</form_id><datafield>";
        input += "<fieldnumber>1</fieldnumber><data><datawords>";
        input += "<datatext1>1234</datatext1><mc2>656865</mc2>";
        input += "</datawords></data></datafield></form></test>";
    
        XDocument documentXDoc = XDocument.Parse(input);
        IEnumerable<XElement> elements = documentXDoc.Descendants("test");
    
        IEnumerable<Receipt> _fuelReceipts =  elements
            .Select(receipt => new Receipt()
            {
                vehicle_number = receipt.Element("vehiclenumber") == null ? "" : receipt.Element("vehiclenumber").Value,
                field = receipt.Descendants("datafield")
                .Select(x => new Field()
                {
                    field_number = x.Element("fieldnumber") == null ? "" : x.Element("fieldnumber").Value,
                    event_data = x.Elements("data").Descendants()
                        .Where(d => !d.HasElements)
                        .ToDictionary(d => d.Name.LocalName, d => d.Value)
                }).ToList()
            });
    }
    
    class Receipt {
        public string vehicle_number { get; set; }
        public List<Field> field { get; set; }
    }
    
    class Field {
        public string field_number { get; set; }
        public Dictionary<string, string> event_data { get; set; }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多