本文实例讲述了C#递归读取XML菜单数据的方法。分享给大家供大家参考。具体分析如下:
最近在研究一些关于C#的一些技术,纵观之前的开发项目的经验,做系统时显示系统菜单的功能总是喜欢把数据写在数据库表,然后直接读取加载到菜单树上显示。
现在想把菜单数据都放在XML里,然后递归读取XML。
由于项目使用WCF,实体类使用了两个,一个是业务逻辑层中的实体,一个是调用业务逻辑层递归方法后进行数据实体的转换,XML读取方法写在业务逻辑层中。
思路:
1.先读取XML里所有的菜单
2.根据用户的权限显示所属用户的菜单加载到页面上
XML数据如下:
<?xml version="1.0" encoding="utf-8"?> <ZCSoft.Net xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <Applications> <Application ID ="OA" Text="OA管理系统"> <Modules> <Module ID="OA_System" Text="系统管理"> <Menus> <Menu ID="OA_System_UserManager" Text="人员管理" URL="System/UserManager/UserManagerList.aspx"> </Menu> <Menu ID="OA_System_RoleManager" Text="角色管理" URL="System/RoleManager/RoleManagerList.aspx"></Menu> <Menu ID="OA_System_LoginLog" Text="登录日志" URL="System/Log/LoginLogList.aspx"></Menu> <Menu ID="OA_System_OperateLog" Text="操作日志" URL="System/Log/OperateLogList.aspx"></Menu> </Menus> </Module><Module ID="OA_TargetManage" Text="目标管理"> <Menus> <Menu ID="OA_TargetManage_TargetSetup" Text="目标设定" URL="OA/TargetManage/TargetSetupList.aspx"> </Menu> </Menus> </Module> </Modules> </Application> </ZCSoft.Net>
菜单的业务逻辑实体类:
public class MenuTreeSearchModel { //菜单ID public string ItemCode { get; set; }//菜单名称 public string ItemName { get; set; }
//菜单显示类型 public string ItemType { get; set; }
//排序 public int ItemOrder { get; set; }
//是否显示 public bool Visible { get; set; }
//菜单链接 public string ItemUrl { get; set; }
//上级ID public string ParentItem { get; set; }
//系统平台ID public string ApplicationCode { get; set; }
//系统平台名称 public string ApplicationName { get; set; }
//模块ID public string ModuleCode { get; set; }
//模块名称 public string ModuleName { get; set; } }
递归方法,读取每个模块和模块下的菜单:
protected void GetChildMenuList(XElement root, List<MenuTreeSearchModel> menuTreeList) { var firstNode = root.FirstNode as XElement;//读取root节点内的第一个节点 if (null != firstNode) { //读取root节点下面同级的所有节点 var appList = from ele in root.Element(firstNode.Name.LocalName).Elements() select ele;bool thisVisible = true;//默认节点是可见的 XAttribute thisAttr = root.Attribute("Display"); if (null != thisAttr)//如果菜单的上级模块有显示属性 { string thisDisplay = thisAttr.Value; thisVisible = thisDisplay.ToLower() == "false" ? false : true; }
foreach (var application in appList) { //模块Display属性 XAttribute modAttr = application.Attribute("Display"); bool visible = true; if (null != modAttr) { string display = application.Attribute("Display").Value; visible = display.ToLower() == "false" ? false : true; } var nextNode = application.FirstNode as XElement;//该节点的下级节点 string itemType = "Folder";//目录还是菜单 string itemUrl = null;//链接地址 string parentItem = null;//上一节点ID string applicationCode = null;//平台编码 string applicationName = null;//平台名称 string moduleCode = null;//模块编码 string moduleName = null;//模块名称
if (application.Name.LocalName == "Application") { applicationCode = application.Attribute("ID").Value; applicationName = application.Attribute("Text").Value; }
if (application.Name.LocalName == "Module") { moduleCode = application.Attribute("ID").Value; moduleName = application.Attribute("Text").Value; applicationCode = root.Attribute("ID").Value; applicationName = root.Attribute("Text").Value;
if (thisVisible) //如果该模块的所属平台中的Display属性设置为可见true(注意:没有设置则默认为可见),则模块的上级为Application的ID { parentItem = root.Attribute("ID").Value; } }
if (application.Name.LocalName == "Menu") { itemType = "Menu"; itemUrl = application.Attribute("URL").Value; moduleCode = root.Attribute("ID").Value; moduleName = root.Attribute("Text").Value; applicationCode = root.Parent.Parent.Attribute("ID").Value; applicationName = root.Parent.Parent.Attribute("Text").Value;
if (thisVisible) //如果该菜单的所属模块中的Display属性设置为可见true(注意:没有设置则默认为可见),则菜单的上级为Module的ID { parentItem = root.Attribute("ID").Value; } else//如果该菜单的所属模块中的Display属性设置为不可见false,则菜单的上级为Application的ID { parentItem = root.Parent.Parent.Attribute("ID").Value; } }
MenuTreeSearchModel model = new MenuTreeSearchModel(); model.ItemCode = application.Attribute("ID").Value; model.ItemName = application.Attribute("Text").Value; model.ItemType = itemType; model.ItemOrder = 0; model.Visible = visible; model.ItemUrl = itemUrl; model.ParentItem = parentItem; model.ApplicationCode = applicationCode; model.ApplicationName = applicationName; model.ModuleCode = moduleCode; model.ModuleName = moduleName; menuTreeList.Add(model);
if (null != nextNode)//如果还有下级节点 { //调用递归 GetChildMenuList(application, menuTreeList); } } } }
从XML文档读取:
/// <summary> /// 从XML文件读取菜单节点 /// </summary> /// <returns></returns> public List<MenuTreeSearchModel> GetMenuTreeByReadXML() { List<MenuTreeSearchModel> list = new List<MenuTreeSearchModel>(); //读取XML文档路径,这里我把XML放在网站的bin目录里 string xmlPath = AppDomain.CurrentDomain.BaseDirectory + "Foundation.xml"; XElement root = XElement.Load(xmlPath); var appList = from ele in root.Element("Applications").Elements() select ele; //按系统平台筛选 foreach (var application in appList) { MenuTreeSearchModel model = new MenuTreeSearchModel(); model.ItemCode = application.Attribute("ID").Value; model.ItemName = application.Attribute("Text").Value; model.ItemType = "Folder"; model.ItemOrder = 0; model.Visible = true; model.ItemUrl = null; model.ParentItem = null; model.ApplicationCode = application.Attribute("ID").Value; model.ApplicationName = application.Attribute("Text").Value; model.ModuleCode = null; model.ModuleName = null; list.Add(model);//递归调用 GetChildMenuList(application, list); }
return list; }
以下是在调用服务契约方法时进行的实体类:
public class PublicUserMenuTreeData { //菜单ID public string ItemCode { get; set; }//菜单名称 public string ItemName { get; set; }
//菜单显示类型 public string ItemType { get; set; }
//排序 public int ItemOrder { get; set; }
//是否显示 public bool Visible { get; set; }
//菜单链接 public string ItemUrl { get; set; }
//上级ID public string ParentItem { get; set; }
//系统平台ID public string ApplicationCode { get; set; }
//系统平台名称 public string ApplicationName { get; set; }
//模块ID public string ModuleCode { get; set; }
//模块名称 public string ModuleName { get; set; } //当前菜单下的菜单集合 public List<PublicUserMenuTreeData> UserMenuTreeDatas { set; get; } }
实体转换方法:
public PublicUserMenuTreeData TransferUserMenuTreeToPublicUserMenu(MenuTreeData userMenuTreeData) { PublicUserMenuTreeData pubUserMenuTreeData = new PublicUserMenuTreeData(); pubUserMenuTreeData.ItemCode = userMenuTreeData.ItemCode; pubUserMenuTreeData.ItemName = userMenuTreeData.ItemName; pubUserMenuTreeData.ItemType = userMenuTreeData.ItemType; pubUserMenuTreeData.ItemOrder = userMenuTreeData.ItemOrder; pubUserMenuTreeData.Visible = userMenuTreeData.Visible; pubUserMenuTreeData.ItemUrl = userMenuTreeData.ItemUrl; pubUserMenuTreeData.ParentItem = userMenuTreeData.ParentItem; pubUserMenuTreeData.ApplicationCode = userMenuTreeData.ApplicationCode; pubUserMenuTreeData.ApplicationName = userMenuTreeData.ApplicationName; pubUserMenuTreeData.ModuleCode = userMenuTreeData.ModuleCode; pubUserMenuTreeData.ModuleName = userMenuTreeData.ModuleName; return pubUserMenuTreeData; }
用户权限菜单方法:
/// <summary> /// 有用户权限树获取共用的用户菜单列表 /// </summary> /// <param name="listAllUserMenu"></param> /// <returns></returns> public List<PublicUserMenuTreeData> GetPublicUserMenuFromUserMenuTreeData(List<MenuTreeData> listAllUserMenu) { List<PublicUserMenuTreeData> listPublicUserMenuTreeData = new List<PublicUserMenuTreeData>(); List<MenuTreeData> list = listAllUserMenu.FindAll(d => string.IsNullOrEmpty(d.ParentItem)).ToList(); foreach (var userMenuTreeData in list) { PublicUserMenuTreeData pubUserMenuTreeData = TransferUserMenuTreeToPublicUserMenu(userMenuTreeData); pubUserMenuTreeData.UserMenuTreeDatas = GetChildData(pubUserMenuTreeData.ItemCode, listAllUserMenu); listPublicUserMenuTreeData.Add(pubUserMenuTreeData); } return listPublicUserMenuTreeData; } public List<PublicUserMenuTreeData> GetChildData(string parentId, List<MenuTreeData> listUserMenuTreeData) {List<MenuTreeData> list = listUserMenuTreeData.FindAll(d => d.ParentItem == parentId).ToList(); if (list.Count > 0) { List<PublicUserMenuTreeData> listPublicUserMenuTreeData = new List<PublicUserMenuTreeData>(); foreach (var userMenuTreeData in list) { PublicUserMenuTreeData pubUserMenuTreeData = TransferUserMenuTreeToPublicUserMenu(userMenuTreeData); pubUserMenuTreeData.UserMenuTreeDatas = GetChildData(pubUserMenuTreeData.ItemCode, listUserMenuTreeData); listPublicUserMenuTreeData.Add(pubUserMenuTreeData); } return listPublicUserMenuTreeData; } return null; }
系统菜单类:
/// <summary> /// 系统菜单 /// </summary> [DataContract()] public class MenuTreeData {[DataMember()] public string ItemCode { get; set; }
[DataMember()] public string ItemName { get; set; }
[DataMember()] public string ItemType { get; set; }
[DataMember()] public int ItemOrder { get; set; }
[DataMember()] public bool Visible { get; set; }
[DataMember()] public string ItemUrl { get; set; }
[DataMember()] public string ParentItem { get; set; }
[DataMember()] public string ApplicationCode { get; set; }
[DataMember()] public string ApplicationName { get; set; }
[DataMember()] public string ModuleCode { get; set; }
[DataMember()] public string ModuleName { get; set; }
}
后台页面加载Load代码:
string menuData = string.Empty; var treeList= GetMenuTreeList(); if (treeList!= null) { List<MenuTreeData> listAllUserMenu = treeList.FindAll(d => d.Visible).OrderBy(d => d.ItemOrder).ToList(); List<PublicUserMenuTreeData> listPublicUserMenuTreeData = GetPublicUserMenuFromUserMenuTreeData(listAllUserMenu); menuData = JsonConvert.SerializeObject(listPublicUserMenuTreeData); }
页面加载脚本,这里使用Jquery:
var obj = menuData; GetMenuInfo(obj); function GetMenuInfo(obj) { var str = ""; var objInfo = ""; if (obj) { objInfo = obj.split("|"); if (objInfo[0] != "") { var PublicUserMenuTreeData = JSON.parse(objInfo[0]); for (var i = 0; i < PublicUserMenuTreeData.length; i++) { str += ("<li>"); var tempmenu= PublicUserMenuTreeData[i]; if (tempmenu.ItemType && tempmenu.ItemType == "Menu") { str += ("<a href='#' onclick='" + tempmenu.ItemCode + "()' id='" + tempmenu.ItemCode + "'>" + tempmenu.ItemName + "</a>"); str += ("<script> function " + tempmenu.ItemCode); str += ("() { tabframe1.newTab({ title: '" + tempmenu.ItemName + "',"); if (tempmenu.ItemUrl.indexOf('?') != -1) { str += ("src: '" + tempmenu.ItemUrl + "&applicationid=" + tempmenu.ApplicationCode + "&moduleid=" + tempmenu.ModuleCode + "',"); } else { str += ("src: '" + tempmenu.ItemUrl + "?applicationid=" + tempmenu.ApplicationCode + "&moduleid=" + tempmenu.ModuleCode + "',"); }str += (" id: 'oa-system-" + tempmenu.ItemCode + "',"); str += (" closable: true }); jQuery('#mainmenulist').hide(); return false; }<\/script>"); } else { str += ("<a href='#' id='" + PublicUserMenuTreeData[i].ItemCode + "'>" + PublicUserMenuTreeData[i].ItemName + "</a>"); }
if (PublicUserMenuTreeData[i].UserMenuTreeDatas) { str += GetRecurrenceData(PublicUserMenuTreeData[i].UserMenuTreeDatas); } str += (" </li>"); } } }
function GetRecurrenceData(listPublicUserMenuTreeData) { var str = ""; if (listPublicUserMenuTreeData && listPublicUserMenuTreeData.length>0) { str += (" <ul>"); for (var j = 0; j < listPublicUserMenuTreeData.length; j++) { str += ("<li class='divFontWeight'>"); if (listPublicUserMenuTreeData[j].ItemType && listPublicUserMenuTreeData[j].ItemType == "Menu") { str += ("<a href='#' onclick='" + listPublicUserMenuTreeData[j].ItemCode + "()' id='" + listPublicUserMenuTreeData[j].ItemCode + "'>" + listPublicUserMenuTreeData[j].ItemName + "</a>"); str += ("<script> function " + listPublicUserMenuTreeData[j].ItemCode); str += ("() { tabframe1.newTab({ title: '" + listPublicUserMenuTreeData[j].ItemName + "',"); if (listPublicUserMenuTreeData[j].ItemUrl.indexOf('?') != -1) { str += ("src: '" + listPublicUserMenuTreeData[j].ItemUrl + "&applicationid=" + listPublicUserMenuTreeData[j].ApplicationCode + "&moduleid=" + listPublicUserMenuTreeData[j].ModuleCode + "',"); } else { str += ("src: '" + listPublicUserMenuTreeData[j].ItemUrl + "?applicationid=" + listPublicUserMenuTreeData[j].ApplicationCode + "&moduleid=" + listPublicUserMenuTreeData[j].ModuleCode + "',"); }
str += (" id: 'oa-system-" + listPublicUserMenuTreeData[j].ItemCode + "',"); str += (" closable: true }); jQuery('#mainmenulist').hide(); return false; }<\/script>"); } else { str += ("<a href='#' id='" + listPublicUserMenuTreeData[j].ItemCode + "'>" + listPublicUserMenuTreeData[j].ItemName + "</a>"); }
var ListMenuDatas = listPublicUserMenuTreeData[j].UserMenuTreeDatas; str += GetRecurrenceData(ListMenuDatas);
str += ("</li>"); } str += (" </ul>"); } return str; }
效果图:
这里补充一下:菜单中如果在模块Module里设置属性Display="false",则模块不显示出来,可是模块下的菜单可显示出来。
itemType="Folder"显示类型是目录,itemType="Menu"显示类型是菜单
希望本文所述对大家的C#程序设计有所帮助。
问题内容: (希望)对某些人来说,这是一个非常简单的问题。 我有一个来自mySQL数据库的递归菜单,现在我的主要问题是: 创建URL的最佳方法是什么?我希望输入每行的标题,例如/ eggs / milk / bacon /。鸡蛋处于0级,例如:鸡蛋0,牛奶1,培根2。关于如何动态输出此内容的任何想法? 对于“ cletus”所说的这个问题,我几乎要去做些评论:PHP / MySQL- 建立导航菜单
本文向大家介绍php菜单/评论数据递归分级算法的实现方法,包括了php菜单/评论数据递归分级算法的实现方法的使用技巧和注意事项,需要的朋友参考一下 在开发过程中经常会遇到分级场景,如菜单分级、评论、商品类型分级等;在同一张mysql数据表中可能设计单表结构,如同如下数据: 这时候在处理展示过程就需要将上面的结构转换为更加直观的数据结构, 形如: 算法代码如下: happy coding! 每一个不
问题:我想不出根据我的具体情况制作递归函数的方法。 情况: 其中向切换类别显示这是子类别。 HTML应该是什么样子的: 我需要什么样的PHP函数来打印出来?
我想以前也有人问过类似的问题,但我不知道我想做的事情在逻辑上是否可行。 我目前在我们的内部网上使用DDSmoothMenu列出我们所有员工都可以访问的文档。 菜单结构类似于: 菜单的基本结构如下: 我认为它必须涉及某种多维数组和递归目录迭代器,但我希望遍历每个文件夹并创建如上所述的HTML布局。 我认为可以做开始标记,但不确定在目录全部列出后如何做结束标记。
我遇到了一个问题,在我已经工作的递归函数中添加了一个助手方法,只使用了2个参数,当添加第三个(助手方法)时,我的代码中断并寻找解决方案。该程序使用扫描仪对字符串进行键盘输入,对字符进行另一次输入,然后输出字母的出现次数。该错误发生在第二条if语句和两条return语句上。在第二次键盘输入后,我发现了错误: 线程"main"中的异常java.lang.StringIndexOutOfBoundsEx
本文向大家介绍C++实现递归函数的方法,包括了C++实现递归函数的方法的使用技巧和注意事项,需要的朋友参考一下 递归函数通俗来讲就是自己调用自己本身。这样有很大的好处,代码很方便简洁,把复杂的有规律的运算交给计算机去做。 1、首先定义问题。递归函数(recursion)需要设置一个函数,然后再可以循环往复的执行下去。 2、把问题换成公式。 如把阶乘之和定义为f(n)=n*f(n-1)。也就是说n*