惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Microsoft Azure Blog
Microsoft Azure Blog
S
Securelist
V
Vulnerabilities – Threatpost
C
Cyber Attacks, Cyber Crime and Cyber Security
Schneier on Security
Schneier on Security
Cyberwarzone
Cyberwarzone
Simon Willison's Weblog
Simon Willison's Weblog
Hacker News - Newest:
Hacker News - Newest: "LLM"
P
Palo Alto Networks Blog
T
Troy Hunt's Blog
SecWiki News
SecWiki News
Security Archives - TechRepublic
Security Archives - TechRepublic
T
The Blog of Author Tim Ferriss
Project Zero
Project Zero
Microsoft Security Blog
Microsoft Security Blog
The Register - Security
The Register - Security
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
J
Java Code Geeks
F
Full Disclosure
阮一峰的网络日志
阮一峰的网络日志
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Attack and Defense Labs
Attack and Defense Labs
Know Your Adversary
Know Your Adversary
WordPress大学
WordPress大学
PCI Perspectives
PCI Perspectives
N
News | PayPal Newsroom
The Last Watchdog
The Last Watchdog
酷 壳 – CoolShell
酷 壳 – CoolShell
P
Privacy & Cybersecurity Law Blog
P
Proofpoint News Feed
V
Visual Studio Blog
C
CERT Recently Published Vulnerability Notes
H
Help Net Security
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
云风的 BLOG
云风的 BLOG
月光博客
月光博客
T
The Exploit Database - CXSecurity.com
I
InfoQ
大猫的无限游戏
大猫的无限游戏
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
U
Unit 42
腾讯CDC
小众软件
小众软件
V2EX - 技术
V2EX - 技术
罗磊的独立博客
Cloudbric
Cloudbric
Recorded Future
Recorded Future
IT之家
IT之家
Google DeepMind News
Google DeepMind News
C
CXSECURITY Database RSS Feed - CXSecurity.com

博客园 - -Enchant

Linux上搭建Asp.net MVC3环境(CentOS + Nginx + Mono) 《单例模式》你需要注意的问题 系统框架整理 Extjs prompt 显示密码框 Python网页抓取、模拟登录 单点登录(SSO)的一点思考 Jquery以JSON方式调用WebService WCF初探 关于抓取百度搜索内容 iPhone开发环境搭建(备忘) SMTP/POP3命令简介(转) C/S模式下 简单的定时任务功能 Asp.net MVC2学习笔记索引 Oracle 调优 Oracle常见错误 @OutputCache指令参数 关于ACL权限控制【ASP.NET MVC2】 ASP.NET MVC2 Ajax返回JSON 引用类型的对象复制(浅复制和深复制)
c#递归生成XML
-Enchant · 2010-04-04 · via 博客园 - -Enchant

本次内容:使用递归生成无限极XML

递归方法大家应该都很熟悉了,简而言之就是方法内部调用自己,就这样不断重复重复再重复的执行,

不过要担心死循环哟。。。

当我们系统需要动态生成菜单时,也就是说我们系统的菜单是存在数据库中的,数据库结构类似于:

ID,Name,Parent_ID 这种设计方法的时候,我们就需要根据ID 和 Parent_ID的关系来动态生成菜单。。

至于怎么生成菜单,今天就不介绍了,今天主要介绍的是 使用递归的方式来生成XML结构的文档。。

1 using System;
2  using System.Collections.Generic;
3  using System.Linq;
4  using System.Text;
5  using System.Data;
6  using System.Collections;
7 using System.Xml;
8
9 using NUnit.Framework;
10
11 namespace H.MySystem.Test
12 {
13 [TestFixture]
14 class MyTest
15 {
16 public DataTable InitTable()
17 {
18 DataTable dt = new DataTable();
19
20 dt.Columns.Add("ID",typeof(string));
21 dt.Columns.Add("Name", typeof(string));
22 dt.Columns.Add("Parent_ID", typeof(string));
23
24 DataRow row1 = dt.NewRow();
25 row1["ID"] = "1";
26 row1["Name"] = "第一个节点";
27
28 DataRow row11 = dt.NewRow();
29 row11["ID"] = "11";
30 row11["Name"] = "第4个节点";
31 row11["Parent_ID"] = "2";
32
33 DataRow row2 = dt.NewRow();
34 row2["ID"] = "2";
35 row2["Name"] = "第二个节点";
36 row2["Parent_ID"] = "1";
37
38 DataRow row3 = dt.NewRow();
39 row3["ID"] = "3";
40 row3["Name"] = "第3个节点";
41 row3["Parent_ID"] = "1";
42
43 dt.Rows.Add(row1);
44 dt.Rows.Add(row2);
45 dt.Rows.Add(row3);
46 dt.Rows.Add(row11);
47 return dt;
48 }
49 //最终XML文档
50 XmlDocument xd = new XmlDocument();
51 //已经使用过的节点ID
52 ArrayList usedElement = new ArrayList();
53
54 [Test]
55 public void TestBuild()
56 {
57 //初始化测试数据
58 DataTable dt = InitTable();
59
60 //新建一个根节点
61 XmlElement xe = xd.CreateElement("Datas");
62 xd.AppendChild(xe);
63
64 //执行递归,添加XML节点
65 BTest(dt, xe);
66
67 System.Console.WriteLine(xd.OuterXml);
68 Assert.AreNotEqual(0, dt.Rows.Count);
69 }
70
71 /// <summary>
72 /// 递归添加XML节点
73 /// </summary>
74 /// <param name="dt">数据源</param>
75 /// <param name="node">当前节点</param>
76 public void BTest(DataTable dt, XmlElement node)
77 {
78 XmlElement tmp;
79
80 var list = from r in dt.AsEnumerable()
81 select r;
82 if (node != null && node.Attributes["ID"] != null)
83 {
84 list = from r in dt.AsEnumerable()
85 where r["Parent_ID"].ToString().Equals(node.Attributes["ID"].Value)
86 select r;
87 }
88 foreach (var row in list)
89 {
90 if (!usedElement.Contains(row["ID"].ToString()))
91 {
92 usedElement.Add(row["ID"].ToString());
93 tmp = xd.CreateElement("Item");
94 tmp.SetAttribute("ID", row["ID"].ToString());
95 tmp.SetAttribute("Name", row["Name"].ToString());
96 tmp.SetAttribute("Parent_ID", row["Parent_ID"].ToString());
97
98 node.AppendChild(tmp);
99 //node = tmp;
100
101 BTest(dt, tmp);
102 }
103 }
104 }
105 }
106 }
107

 代码如上:

 主要思路就是每次执行 递归方法时,根据传入的当前XML节点,找到属于该节点的下一级节点(根据ID和Parent_ID查找)

这里还有一点需要注意的是我使用了一个集合(usedElement)来存放已经执行过、已经找到自己位置的ID,如果不把已经找到自己位置的ID排除的话,那么递归出来的结果就不正确了。。。

上面只测试了几条数据,不知道数据量大的情况下这种算法能否吃的消,呵呵。。