欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C#递归读取XML菜单数据的方法

程序员文章站 2023-12-15 10:30:22
本文实例讲述了c#递归读取xml菜单数据的方法。分享给大家供大家参考。具体分析如下: 最近在研究一些关于c#的一些技术,纵观之前的开发项目的经验,做系统时显示系统菜单的功...

本文实例讲述了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;
}

效果图:

C#递归读取XML菜单数据的方法

这里补充一下:菜单中如果在模块module里设置属性display="false",则模块不显示出来,可是模块下的菜单可显示出来。

itemtype="folder"显示类型是目录,itemtype="menu"显示类型是菜单

希望本文所述对大家的c#程序设计有所帮助。

上一篇:

下一篇: