C#递归读取XML菜单数据的方法
本文实例讲述了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#程序设计有所帮助。