【问题标题】:Loading duplicate XML attributes using XDocument使用 XDocument 加载重复的 XML 属性
【发布时间】:2011-12-22 18:53:21
【问题描述】:

我需要使用 XDocument 加载 xml 的帮助。 xml 保存 WPF 中 HierarchicalDataTemplate 的数据,因此每个元素都具有相同的属性。

我遇到了一个新手问题,如何处理重复的属性名称、图像和文件位置。

我试图让下面的代码工作,但正如你所见,重复的属性将不起作用。

public static List<MenuItem> Load(string MyMenuFile)
{       
    var mymenu = XDocument.Load(MyMenuFile).Root.Elements("Menu").Select(
            x => new MenuItem(
            (string)x.Attribute("id"),
                (string)x.Attribute("name"),
                (string)x.Attribute("image"),
                (string)x.Attribute("fileLoc"),
                (string)x.Element("itemlist"),
        (string)x.Attribute("name"),
                (string)x.Attribute("image"),
                (string)x.Attribute("fileLoc"),
                (string)x.Element("item"),
                (string)x.Attribute("name"),
                (string)x.Attribute("image"),
                (string)x.Attribute("fileLoc")));

    return stationfiles.ToList();
}

这里是xml:

<Menus>
    <Menu id="1"  Name="Level1" image="C:\lvl1.jpg" fileLoc="C:\lvl1.xml">
    </Menu>
    <Menu id="2"  Name="Level2" image="C:\lvl2.jpg" >
        <itemlist Name="Level2" image="C:\lvl2.jpg" fileLoc="C:\lvl2.xml">
        </itemlist>
        <itemlist Name="Level3" image="C:\lvl3.jpg">
            <item Name="First" image="C:\first.jpg" fileLoc="C:\first.xml"></item>
            <item Name="Second" image="C:\second.jpg" fileLoc="C:\second.xml"></item>
            <item Name="Third" image="C:\third.jpg" fileLoc="C:\third.xml"></item>
        </itemlist>
    </Menu>
</Menus>

如您所见,不同的元素但重复的属性。我应该有 3 个单独的类,但我将如何将它们组合为 XDocument 负载?任何帮助都会很棒。

【问题讨论】:

  • 我对@9​​87654326@、&lt;itemlist&gt;item 都应该是MenuItem 的理解是否正确?我是否正确&lt;itemlist&gt; 也可以有&lt;itemlist&gt;?还是停在&lt;item&gt; 级别?
  • 我明白你的意思了,根是Menus,下一个元素是带有属性的菜单,下一个是带有属性的itemlist(可选),下一个是带有属性的item(也是可选的)在上面的xml中, Menu id=1 没有 itemlist 或 item,Menu id=2 有两个 itemlist 但只有第二个有 item。一个项目列表将只有属性和项目。

标签: c# wpf xml linq-to-xml


【解决方案1】:

这假定这些是 MenuItem 的直接元素和属性。我怀疑您需要读取元素 itemslist 和 items 的属性。不知道如何用一个循环来做到这一点。您需要遍历元素,然后循环属性,以便 THAT 元素(不是父元素)。

【讨论】:

    【解决方案2】:

    您在处理过程中没有分层。

    我已经调整了您的 xml,但这里是您应该如何处理它的示例:

    string xml = @"<?xml version=""1.0"" encoding=""UTF-8""?>
    <Menus> 
        <Menu id=""1""  Name=""Level1 - Alpha"" image=""C:\lvl1.jpg"" fileLoc=""C:\lvl1.xml""/> 
        <Menu id=""2""  Name=""Level1 - Beta"" image=""C:\lvl2.jpg"" fileLoc=""C:\lvl1.xml"" > 
            <itemlist Name=""Level2-Gamma"" image=""C:\lvl2.jpg"" fileLoc=""C:\lvl2.xml""/>  
            <itemlist Name=""Level3-Zeta"" image=""C:\lvl3.jpg"" fileLoc=""C:\lvl1.xml""> 
                <item Name=""First"" image=""C:\first.jpg"" fileLoc=""C:\first.xml""></item> 
                <item Name=""Second"" image=""C:\second.jpg"" fileLoc=""C:\second.xml""></item> 
                <item Name=""Third"" image=""C:\third.jpg"" fileLoc=""C:\third.xml""></item> 
            </itemlist> 
        </Menu> 
    </Menus>";
    
    var xd = XDocument.Parse(xml);
    
    var result = 
    
    xd.Descendants("Menu")
      .Select (l1 => new 
      {
       Name     = l1.Attribute("Name").Value, 
       Image    = l1.Attribute("image").Value, 
       File     = l1.Attribute("fileLoc"),
       Children = l1.Descendants("itemlist")
                      .Select (l2 => new {
                                    Name     = l2.Attribute("Name").Value, 
                                    Image    = l2.Attribute("image").Value, 
                                    File     = l2.Attribute("fileLoc"),
                                    Children = l2.Descendants("item")
                                                    .Select (l3 => new {
                                                            Name  = l3.Attribute("Name").Value, 
                                                            Image = l3.Attribute("image").Value, 
                                                            File  = l3.Attribute("fileLoc")
                                                                        })
                      })
    
    });
    
    Console.WriteLine (result );
    

    这是从 linqpad 中找到的结果:

    查看数据是如何解析出来的,这就是您需要如何使用它才能将其放入菜单结构中。没有重复的属性。 :-)

    HTH

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-02
      • 2011-06-01
      • 1970-01-01
      相关资源
      最近更新 更多