C# Linq to XML - 解析嵌套对象列表

3

我目前有一个XML文件格式,大致如下(为了易读性添加了空格和省略号):

<root>
    <Module>          //Start with list of Modules
        <ModuleParams>
        </ModuleParams>
    </Module>
    ...

    <DetectLine>      //Now a list of DetectLines
        <DetectLineParams>
        </DetectLineParams>

        <Channels>    //List of Channels embedded in each DetectLine
            <Channel>
                <ChannelParams>
                </ChannelParams>
            </Channel>
            ...

        </Channels>
    </DetectLine>
    ...

</root>

以下是结构化的类:

public class Module
{
    public ModuleParams { get; set; }
}

public class DetectLine
{
    public DetectLineParams { get; set; }
    public List<Channel> Channels { get; set; }
}

public class Channel
{
    public ChannelParams { get; set; }
}

使用Linq to XML可以很容易地解析模块列表和DetectLines列表。但是,对于每个DetectLine解析Channel列表并不像我想象的那么简单。使用Linq to XML能够做到这一点吗?我宁愿不重构代码以便使用XMLSerializer。

初始代码(openXML是OpenFileDialog实例,已检查文件名是否正确):

List<Module> myModules;
List<DetectLine> myDetectLines;
XDocument config = XDocument.Load(openXML.FileName);

myModules =
         (from myElements in config.Descendants("Module")
          select new Module()
          {
              ModuleParam1 = (string)myElements.Element("ModuleParam1"),
              ModuleParam2 = (string)myElements.Element("ModuleParam2"),
              ...
          }).ToList<Module>();

myDetectLines =
          (from myElements in config.Descendants("DetectLine")
           select new DetectLine()
           {
              DetectLineParam1 = (string)myElements.Element("ModuleParam1"),
              DetectLineParam2 = (string)myElements.Element("ModuleParam2"),
              ...

              // ?? Add Channels list here somehow...
           }).ToList<DetectLine>();

请提供您的模块和检测线代码。 - MarcinJuraszek
我将类保持如此通用的原因是因为实际参数由我决定(这是我定义和保存的程序配置文件。格式只是为了方便手动阅读/调试/编写)。我已经添加了我的当前解析方法,以展示我正在寻找什么。我不需要有人解决XML或类本身,只需要关于使用Linq查询进行解析的建议。 - Bandoth
1个回答

2

With

XElement detectLine = XElement.Parse(@"<DetectLine>      
        <DetectLineParams>
        </DetectLineParams>

        <Channels>    
            <Channel>
                <ChannelParams>
                </ChannelParams>
            </Channel>
            ...

        </Channels>
    </DetectLine>
");

你可以例如做以下操作。
DetectLine dl1 = new DetectLine() {
  DetectLineParams = ...,
  Channels = (from channel in detectLine.Element("Channels").Element("Channel")
             select new Channel() {
                 ChannelParams = new ChannelParams() { ... = channel.Element("ChannelParams").Value }
             }).ToList();

我们需要看到更多具体的C#类代码,以明确如何设置完整的查询。
[编辑] 为了适应您现在发布的代码:
myDetectLines =
          (from myElements in config.Descendants("DetectLine")
           select new DetectLine()
           {
              DetectLineParam1 = (string)myElements.Element("ModuleParam1"),
              DetectLineParam2 = (string)myElements.Element("ModuleParam2"),
              ...

              Channels = (from channel in myElements.Element("Channels").Element("Channel")
                 select new Channel() {
                     ChannelParams = new ChannelParams() { ... = channel.Element("ChannelParams").Value }
                 }).ToList();
           }).ToList<DetectLine>();

问题在于XML文件中定义了多个DetectLines。这要求我创建一个DetectLines列表,其中每个单独的DetectLine都有一个通道列表(只是添加了我的初始解析方法来解释我的意思)。 - Bandoth
我怎么会忽略了那个?教训学到了:永远不要空着肚子编码。非常感谢您! - Bandoth

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接