测试XML属性的值以创建对象

时间:2014-04-29 09:47:59

标签: c# linq xml-parsing linq-to-objects

我试图使用linq从XML文件中获取数据,并将它们转换为对象。

但我的XML文件中的一些数据是这样的:

<XMLFILE>
    <Machines>
            <Alias name="MACHINE_AAA_1" />
            <Alias name="MACHINE_AAA_2" />
            <Alias name="MACHINE_AAA_3" />
            <Alias name="MACHINE_BBB_1" />
            <Alias name="MACHINE_BBB_2" />
            <Alias name="MACHINE_BBB_3" />
            <Alias name="MACHINE_CCC_1" />
            <Alias name="MACHINE_CCC_2" />
            <Alias name="MACHINE_DDD_1" />
    </Machines>
</XMLFILE>

我想要做的是创建机器AAA,BBB,CCC和DDD。

目前,我的代码是:

Data DataMachines= new Data
{
    Machines = (from _alias in XEle.Elements("Machines").Elements("Alias")
                where _alias.Attribute("name").Valeur.Contains("MACHINE_")
                select new Machine
                {
                    Name=(string)_alias.Attribute("name").Value             
                }).ToList()
};

通过这种方法,我将拥有尽可能多的&#34;机器&#34;因为有#34; Alias&#34;在我的XML文件中。

有没有办法创建对象的 单个实例 &#34; Machine&#34;根据第二个&#34; _&#34;之前的字符?

此代码的目的是创建:  一个实例&#34; Machine_AAA&#34;通道1,2,3,  一个实例&#34; Machine_BBB&#34;通道1,2,3,  一个实例&#34; Machine_CCC&#34;通道1,2,  一个实例&#34; Machine_DDD&#34;与频道1。

对不起,如果不清楚,英语是我的第二语言,C#是我的第三语言。

感谢您的回答。

1 个答案:

答案 0 :(得分:0)

关键是使用下划线分割name属性的值,然后按第二个元素(机器名称)分组。下面是一个代码示例:

const string machinesXml = @"<XMLFILE>
    <Machines>
        <Alias name=""MACHINE_AAA_1"" />
        <Alias name=""MACHINE_AAA_2"" />
        <Alias name=""MACHINE_AAA_3"" />
        <Alias name=""MACHINE_BBB_1"" />
        <Alias name=""MACHINE_BBB_2"" />
        <Alias name=""MACHINE_BBB_3"" />
        <Alias name=""MACHINE_CCC_1"" />
        <Alias name=""MACHINE_CCC_2"" />
        <Alias name=""MACHINE_DDD_1"" />
    </Machines>
</XMLFILE>";

var XEle = XElement.Parse(machinesXml);

// Locate the machines element
var machinesElement = XEle.Element("Machines");

// Split the name
var splitAliasNames = machinesElement.Elements("Alias").Select(a => a.Attribute("name").Value.Split('_'));

// Only take those where the split elements are what we expect
var ofCorrectParts = splitAliasNames.Where(split => split.Length == 3 &&
                                        "MACHINE".Equals(split[0], StringComparison.OrdinalIgnoreCase));

var channelForMachine = ofCorrectParts.Select(split => new
{
    MachineName = split[1], 
    ChannelName = split[2]
});

var byMachineName = channelForMachine.GroupBy(s => s.MachineName, StringComparer.OrdinalIgnoreCase);
var machines = byMachineName.Select(g =>
    {
        var channels = g.Select(s => s.ChannelName).ToList();
        return new Machine
        {
            Name = g.Key,
            Channels = channels
        };
    });

foreach (var machine in machines)
{
    Console.WriteLine("Machine '{0}':", machine.Name);
    foreach (var channel in machine.Channels)
    {
        Console.WriteLine("\tChannel '{0}'", channel);
    }
}
Console.ReadKey(true);