如何用C#生成如下下表关系的XML文件,XML需以这种格式 
<?xml version="1.0" encoding="utf-8" ?> 
<root> 
<c01 code="01" name="政治"> 
<c0101 code="01.01" name="国家概况"> 
<c01010101 code="01.01.01" name="政治体制"> 
<c01010102 code="01.01.01.02" name="领导体制"></c01010102> 
</c01010101> 
</c0101> 
</c01> 
<c01 code="02" name="选举制"> 
... ....... . . . 
</c02> 
</root> 
表里面可能会有很多主要的关系 
ParentCode Code                    Name 
           01                      政治 
01         01.01                   国家概况 
01.01      01.01.01.01             政治体制 
01.01.01   01.01.01.02             领导体制 
             02                      选举制

解决方案 »

  1.   

              ParentCode Code                    Name 
                         01                      政治 
                01        01.01                  国家概况 
                01.01     01.01.01.01            政治体制 
                01.01.01  01.01.01.02             领导体制 
                            02                      选举制
      

  2.   

    将SQL里面的数据读出放入datatable 然后按行获取数据 
    for递归 一行一行写如XML..
    只提供方法.
    不提供代码.
      

  3.   

    我需要把表里的关系按照我上面的规则体现在XML文件里
      

  4.   

    参考MSDN中关于XML的资料就可以了,比如XmlDocument、XmlElement、XmlNode,根据DataRow生成节点,然后保存到XML文件中。
      

  5.   

    你说的这个问题是可以用递归实现,不过还是建议你能不用递归就不用,效率不高不用递归的方法:        //数据库返回的Datatable
            DataTable tb = db.ExecuteDataTable("Select * from 编码表");
            //创建xml文档对象
            XmlDocument doc = new XmlDocument();
            //xml头
            doc.AppendChild(doc.CreateXmlDeclaration("1.0", "utf-8", null)); //声明
            //根元素
            doc.AppendChild(doc.CreateElement("root")); //根节点
            //用于存放临时数据的xml元素数组
            XmlElement[] menu = new XmlElement[tb.Rows.Count];
            for (int i = 0; i < tb.Rows.Count; i++)
            {
                DataRow r = tb.Rows[i];
                //创建一个xml元素并放到文档的根目录下
                menu[i] = doc.CreateElement("c" + r["code"].ToString().Replace(".", "")); ;  //元素名: c+code
                menu[i].SetAttribute("code", r["code"].ToString());//代码
                menu[i].SetAttribute("name", r["name"].ToString()); //名称
                menu[i].SetAttribute("parentCode", r["parentCode"].ToString()); //父代码
                menu[i].SetAttribute("hierarchy", r["hierarchy"].ToString()); //深度
                doc.DocumentElement.AppendChild(menu[i]);
            }
            //重新排列xml所有节点的位置
            for (int i = 0; i < menu.Length; i++)
            {
                if (menu[i].Attributes["hierarchy"].Value != "1") //深度为一的不需要移动,也就是总目录
                {
                    //移动元素,复制一个到父节点下并删除当前元素
                    //根据当前元素判断父元素的元素名
                    string parentNodeName = "c" + menu[i].Attributes["parentCode"].Value;
                    string xpath = string.Format("//{0}[@code={1}]", parentNodeName, menu[i].Attributes["parentCode"].Value);                doc.DocumentElement.SelectSingleNode(xpath).AppendChild(menu[i].Clone());
                    menu[i].ParentNode.RemoveChild(menu[i]);
                    
                }        }
            //现在的xml表现为:
            //<?xml version="1.0" encoding="utf-8" ?> 
            //<root> 
            //<c01 code="01" name="政治" parentCode="" hierarchy="1"> 
            //<c0101 code="01.01" name="国家概况" parentCode="01" hierarchy="2"> 
            //<c010101 code="01.01.01" name="政治体制" parentCode="01.01" hierarchy="3"> 
            //<c01010102 code="01.01.01.02" name="领导体制" parentCode="01.01.01" hierarchy="4"> </c01010102> 
            //</c010101> 
            //</c0101> 
            //</c01> 
            //<c02 code="02" name="选举制" parentCode="" hierarchy="1"> 
            //... ....... . . . 
            //</c02> 
            //</root> 
    //你可以自己再把多余的属性删掉递归的思想其实也简单:生成节点,遍历说有数据,看有没有子数据,有的话继续生成,函数里面继续调用本函数,
    不过效率可能比上面的慢很多,特别是数据很大的时候
      

  6.   

    非常感谢11楼  有个问题 XML文件生成到哪里去了   希望能改造成用户指定路径和文件名
      

  7.   

    doc.save("文件路径")例如:doc.save(Server.MapPath('~/1.xml'));
      

  8.   

    给个xml参考。
    http://blog.csdn.net/greatverve/archive/2008/12/10/3490741.aspx
    http://blog.csdn.net/greatverve/archive/2008/12/22/3582939.aspx
    递归参考:
    http://topic.csdn.net/u/20081115/11/18b4ec0b-9dd6-45a8-b620-fd4b347b6e66.html
      

  9.   

    递归构造一棵树object然后再把这个object序列化成xml。说起来简单,但写起代码来也挺麻烦的。思路就是这样
      

  10.   

    11楼我调试你的代码错误了当menu[i].Attributes["hierarchy"].Value = 3时 提示doc.DocumentElement.SelectSingleNode(xpath).AppendChild(menu[i].Clone());
    这段代码未将对象设置到实例
    还有我数据库里还有的02,03不光是01
      

  11.   

    这是递归的 我已经测试了   protected void Button1_Click(object sender, EventArgs e)
        {
            SqlDataAdapter da = new SqlDataAdapter("select * from [table]", System.Configuration.ConfigurationManager.ConnectionStrings["TestConnectionString"].ConnectionString);
            DataTable dt = new DataTable("tab1");
            da.Fill(dt);
            XmlDocument xd = new XmlDocument();
            XmlDeclaration xdl = xd.CreateXmlDeclaration("1.0", "utf-8", null);
            xd.AppendChild(xdl);
            XmlElement xe = xd.CreateElement("root");
            xe = XmlElementCreate(dt,"",xd,xe);
            xd.AppendChild(xe);
            try
            {
                xd.Save("D://XMLCerate.xml");
                Response.Write("OK");
            }
            catch (Exception ee)
            { 
                Response.Write(ee.Message);
            }
        }    private XmlElement XmlElementCreate(DataTable dt, string parentcode, XmlDocument xd, XmlElement xee)
        {
            string strparentcode="";
            if (parentcode.Trim().Length == 0)
                strparentcode = "parentcode is null";
            else
                strparentcode = "parentcode='" + parentcode + "'";
            DataRow[] dr = dt.Select(strparentcode);
            for (int i = 0; i < dr.Length; i++)
            {
                XmlElement xe = xd.CreateElement("c" + dr[i]["code"].ToString().Replace(".", ""));
                XmlAttribute xaCode = xd.CreateAttribute("code");
                xaCode.Value = dr[i]["code"].ToString();
                xe.Attributes.Append(xaCode);
                XmlAttribute xaName = xd.CreateAttribute("name");
                xaName.Value = dr[i]["name"].ToString();
                xe.Attributes.Append(xaName);
                xe = XmlElementCreate(dt, dr[i]["code"].ToString(), xd, xe);
                xee.AppendChild(xe);
            }
            return xee;
        }
      

  12.   

    用xsd.exe——>强类型的dataset->xml系列化
    参考msdn.
      

  13.   

    这种问题不难吧,你就算不会xml的操作,你可以直接streamwrite.witer(xml_string);
    这种方式写xml也可以的,xml就是txt文件没什么好神秘的
      

  14.   

    你的数据库结构不完整吗 
    是不是有些数据没有 hierarchy code 
    我看你后面发的图 有的数据是空的 
      

  15.   

    我给你的代码是我以前一个项目的源代码改过来的
    应该不会有什么错误的我想你的数据有些不正确的数据,比如有的字段是空的,或者结构不对我那个项目的数据有1W多条,生成的xml文件很正常啊
    不过1W多条数据你用递归我敢保证运行时间>2秒
    我自己测试的,后来才改过来的
      

  16.   

    你把
     if (menu[i].Attributes["hierarchy"].Value != "1") //深度为一的不需要移动,也就是总目录
    改成
     if (menu[i].Attributes["parentcode"].Value != "") 试试 不好意思,因为我不知道你的数据库结构,我猜想你的hierarchy是表示数据层次深度或者你把数据库发给我 我来测试一下
      

  17.   

    ailin84 我把你的代码改造了一下似乎可以了  注意看粗体代码ClassifyProcess cfp = new ClassifyProcess();
                    DataSet ds = cfp.ReadAll();
                    DataTable tb1 = cfp.ClassifyCount().Tables[0];
                    DataTable tb = ds.Tables[0];
                    XmlDocument doc = new XmlDocument();
                    
                    doc.AppendChild(doc.CreateXmlDeclaration("1.0", "gb2312", null));
                    doc.AppendChild(doc.CreateElement("root"));
                    
                    XmlElement[] menu = new XmlElement[tb.Rows.Count];
                    string[] parentCode = new string[tb.Rows.Count];
                    string[] hierarchy = new string[tb.Rows.Count];
                    for (int i = 0; i < tb.Rows.Count; i++)
                    {
                        DataRow r = tb.Rows[i];
                        menu[i] = doc.CreateElement("c" + r["code"].ToString().Replace(".", ""));
                        menu[i].SetAttribute("code", r["code"].ToString());
                        menu[i].SetAttribute("name", r["name"].ToString());
                        menu[i].SetAttribute("value", "");
                        parentCode[i] = r["parentCode"].ToString();
                        hierarchy[i] = r["hierarchy"].ToString();
                        doc.DocumentElement.AppendChild(menu[i]);
                    }
                    for (int i = 0; i < menu.Length; i++)
                    {
                        if (hierarchy[i] != "1")
                        {
                            string parentNodeName = "c" + parentCode[i].Replace(".", "");
                            string xpath = string.Format("//{0}", parentNodeName);
                            doc.DocumentElement.SelectSingleNode(xpath).AppendChild(menu[i].Clone());
                            menu[i].ParentNode.RemoveChild(menu[i]);
                        }
                    }
                    for (int j = 0; j < tb1.Rows.Count; j++)
                    {
                        DataRow r = tb.Rows[j];
                        XmlNode xn = doc.SelectSingleNode("/c" + r["Code"].ToString());
                        xn.Attributes["value"].Value = r["ClassifyCount"].ToString();
                    }
                    doc.Save(path + filename);
      

  18.   

    其实主要是 后面每一个元素要查找他的父元素,要根据自己的parentCode得到父元素的元素名然后复制到父元素下,再删除本元素你的方法和我写的其实意思是一样的
    不过你直接就把 parentCode 和深度信息放到数组里了,我是写成属性到xml里
      

  19.   

    wackyboy 的方法不错  很实用  效率比递归强很多
      

  20.   

    我想问下,关于结点移动,我一使用 string parentNodeName = "c" + menu[i].Attributes["parentCode"].Value;
    时候,我说未将对象引用实例,,,