【问题标题】:How can I use Linq to build a c# object from xml where an element has zero or more elements of the same type?如何使用 Linq 从 xml 构建一个 c# 对象,其中一个元素具有零个或多个相同类型的元素?
【发布时间】:2015-08-25 11:32:39
【问题描述】:

我正在尝试解析一个大致如下所示的 xml 文件:

<?xml version="1.0" encoding="utf-16" ?>
<log>
    <request id="1" result="Deny">
        <user name="corp\joe"/>
        <session number="1"/>
        <file name="xyz"/>
        <policy type="default" name="Default Rules" result="Deny"/>
        <policy type="adgroup" name="Domain Users" result="Allow"/>
    </request>
        <request id="1" result="Deny">
        <user name="corp\joe"/>
        <session number="1"/>
        <file name="abc"/>
        <policy type="default" name="Default Rules" result="Deny"/>
        <policy type="device" name="laptop12" result="Deny"/>
    </request>
</log>

注意每个请求存在多个 policy 元素。

到目前为止,这是我的代码:

public class Request
{
   public int Request_id { get; set; }
   public string User_name { get; set; }
   public string Session_number { get; set; }
   public string File_name { get; set; }
}

void Main()
{
    var xml = XDocument.Load(@"c:\temp\test.xml");

    var query = from c in xml.Descendants("request")
        where (String)c.Attribute("result") == "Deny"
        select new Request() {
            Request_id = (int) c.Attribute("id"),
            User_name = (string) c.Element("user").Attribute("name"),
            Session_number = (string) c.Element("session").Attribute("number"),
            File_name = (string) c.Element("file").Attribute("name"),
        };

    foreach (Request r in query.ToList()) {
        System.Diagnostics.Debug.WriteLine(r.User_name + "," + r.File_name);
    }
}

我不确定如何查询和捕获 0+ 个策略元素。我应该:

  • 定义一个新的类 Policy {Type, Name, Result}
  • 将 List 成员添加到 Request 类中
  • 在创建新的 Request 对象作为 Linq 查询的一部分时以某种方式填充此列表

这是我坚持的不知何故位。我是否需要在现有的 Select 中添加另一个 Linq 查询,如果需要,那会是什么样子? c.Descendents("policy")...

【问题讨论】:

    标签: c# linq


    【解决方案1】:

    你在非常好的轨道上!你的观点是正确的。您需要 Policy 类和 Request 类中的 List&lt;Policy&gt; 属性。有了它,您需要在现有查询中使用子查询来填充它们:

    var query = from c in xml.Descendants("request")
        where (String)c.Attribute("result") == "Deny"
        select new Request() {
            Request_id = (int) c.Attribute("id"),
            User_name = (string) c.Element("user").Attribute("name"),
            Session_number = (string) c.Element("session").Attribute("number"),
            File_name = (string) c.Element("file").Attribute("name"),
            Policies = (from p in c.Elements("policy")
                        select new Policy() {
                            Type = (string) p.Attribute("type")
                            // (...)
                        }).ToList()
        };
    

    【讨论】:

    • 将 p.Element("type") 更改为 p.Attribute("type") 我会将其标记为最佳答案。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-12
    • 1970-01-01
    • 2015-10-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多