我希望创建一个动态XML导航菜单,它由MenuItem和SubMenuItem(两个类)组成。我想解析以下XML并使用LINQ来解析它并检索数据。
以下是XML示例:
<?xml version="1.0" encoding="utf-8" ?>
<MenuItems>
<Item Id="1" Url="Default.aspx" LinkText="Home" Description="Test Description" Target="">
<SubItem Id="1" ParentId="1" Url="Default.aspx" LinkText="SubMenu1" Description="Test Description" Target="" />
<SubItem Id="2" ParentId="1" Url="Default.aspx" LinkText="SubMenu2" Description="Test Description" Target="" />
<SubItem Id="3" ParentId="1" Url="Default.aspx" LinkText="SubMenu3" Description="Test Description" Target="" />
</Item>
<Item Id="2" Url="Default2.aspx" LinkText="Menu2" Description="Test Description" Target="" />
<Item Id="3" Url="Default3.aspx" LinkText="Menu3" Description="Test Description" Target="" />
</MenuItems>
我想使用LINQ,但是语法有问题。您可以使用嵌套的LINQ查询来填充两个对象列表,如下所示吗?
List<MenuItem> MenuItems = null;
try
{
XElement xmlDoc = XElement.Load(xmlPath + xmlFileName);
if (xmlDoc != null)
{
MenuItems =
(from menuItem in xmlDoc.Descendants("Item")
select new MenuItem
{
Id = menuItem.Attribute("Id").Value,
Description = menuItem.Attribute("Description").Value,
LinkText = menuItem.Attribute("LinkText").Value,
Url = menuItem.Attribute("Url").Value,
Target = menuItem.Attribute("Description").Value,
SubMenuItems = (from subMenuItem in xmlDoc.Descendants("SubItem")
select new SubMenuItem
{
Id = menuItem.Attribute("Id").Value,
ParentId = menuItem.Attribute("ParentId").Value,
Description = menuItem.Attribute("Description").Value,
LinkText = menuItem.Attribute("LinkText").Value,
Url = menuItem.Attribute("Url").Value,
Target = menuItem.Attribute("Description").Value,
}).ToList<SubMenuItem>(),
}).ToList<MenuItem>();
}
}
有人可以帮助LINQ将这个XML解析为这两个嵌套在一起的类吗?
public class MenuItem
{
public MenuItem() { }
private string id;
private string url;
private string linkText;
private string description;
private string target;
private List<SubMenuItem> subMenuItems = new List<SubMenuItem>();
public string Id { get { return id; } set { id = value; } }
public string Url { get { return url; } set { url = value; } }
public string LinkText { get { return linkText; } set { linkText = value; } }
public string Description { get { return description; } set { description = value; } }
public string Target { get { return target; } set { target = value; } }
public List<SubMenuItem> SubMenuItems { get { return subMenuItems; } set { subMenuItems = value; } }
}
public class SubMenuItem
{
public SubMenuItem() { }
private string id;
private string parentid;
private string url;
private string linkText;
private string description;
private string target;
public string Id { get { return id; } set { id = value; } }
public string ParentId { get { return parentid; } set { parentid = value; } }
public string Url { get { return url; } set { url = value; } }
public string LinkText { get { return linkText; } set { linkText = value; } }
public string Description { get { return description; } set { description = value; } }
public string Target { get { return target; } set { target = value; } }
}
谢谢!
答案 0 :(得分:2)
如果你更多地隔离你的逻辑可能会有所帮助。最好的选择,IMO,将为接受XElement的MenuItem和SubMenuItem添加一个构造函数。
public class MenuItem
{
public MenuItem() { }
public MenuItem(XElement xmlDoc)
{
this.id = xmlDoc.Element("Id").Value;
this.url = xmlDoc.Element("Url").Value;
// etc.
subMenuItems = (from subMenuItem in xmlDoc.Descendants("SubItem")
select new SubMenuItem(subMenuItem)).ToList();
// etc.
}
public class SubMenuItem
{
public SubMenuItem() { }
public SubMenuItem(XElement xmlDoc)
{
this.id = xmlDoc.Element("Id").Value;
// etc.
}
// etc.
}
这会清除您的初始选择:
MenuItems = (from menuItem in xmlDoc.Descendants("Item")
select new MenuItem(menuItem)).ToList();
答案 1 :(得分:1)
我认为你可以用一点递归来解决这个问题。你可能只有MenuItem而不是两个类。它们基本相同。然后,如果您创建一个SelectDecendants方法,它将继续调用自己来获取当前节点的子节点。像这样:
class Program
{
static void Main(string[] args)
{
var doc = XDocument.Load("input.xml");
var menuItems = SelectDescendants(doc.Elements("MenuItems").Elements());
}
public static List<MenuItem> SelectDescendants(IEnumerable<XElement> menuItems)
{
return (from menuItem in menuItems
select new MenuItem
{
Id = menuItem.Attribute("Id").Value,
Description = menuItem.Attribute("Description").Value,
LinkText = menuItem.Attribute("LinkText").Value,
Url = menuItem.Attribute("Url").Value,
Target = menuItem.Attribute("Description").Value,
SubMenuItems = SelectDescendants(menuItem.Elements()).ToList()
}).ToList();
}
}