DavidJGu's Blog

       尼采说,宁可追求虚无也不能无所追求!  Keeping is harder than winning
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Build TreeView from XML

Posted on 2004-08-31 10:43  Let's DotNet  阅读(623)  评论(0编辑  收藏  举报
  Tree View的生成基本上有三种方式:

1.         界面设计时在Tree View设计器或者代码中直接填充Tree View控件。
这种方式通过拖放控件的方式生成树,应用范围窄,是一种非编程方式;

2.         XML文件中建立树形结构。
这种方式通过XML文件()生成树,从形式上来说,这种方式是比较直观的。因为XML本身就是一棵“树”,在.NET 平台下Tree View的自动生成代码中,Tree View的实际内容也是由XML表示的。此外,基于XML文件生成树对异构环境下的分布式应用(包括Web Service)具有重要意义。事实上,利用XML作为通用数据传递格式已得到普遍认可;

3.  从数据库中得到数据(在.NET中,我们可以理解为一个数据集),建立树形结构。
    这种方式通过父子关系递归生成树,是最容易理解的一种编程实现方式。一般是自顶向下递归生成,得到广泛应用。

 

通过XML文件()生成树。这种方式实现的关键是构造出一个类似于Tree ViewXML文档或字符串出来。其基本思想应该与传统的算法是相似的,只是在程序实现上稍微复杂一些。另外还要注意的是,有很多的第三方Tree View控件,他们所支持的XML文档的格式是不尽相同的,如表1所示。

Tree View控件

XML格式

By Microsoft

<TREENODES>

         <treenode text="Modem" tag="xx">

              <treenode text="Cable" tag="xx">

                   <treenode text="Broken" tag="xx"/>

              ...

              </treenode>

              ...

         </treenode>

          <treenode text="Monitor" tag="xx">

              <treenode text="Fuzzy" tag="xx">

                        <treenode text="Driver" tag="xx"/>

              </treenode>

         </treenode>

              ...

</TREENODES>

By Infragistics(NetAdvantage)

<?xml version='1.0' encoding='utf-8' standalone='yes'?>

<Nodes>

     <Node>

         <Nodes>

              <Node>

                   <Text>Child #1</Text>

                   <Tag>hhee</Tag>

                   <Nodes>

                       <Node>

                            <Text>Sub Child #1</Text>

                       </Node>

                   </Nodes>

              </Node>

              <Node>

                   <Text>Child #2</Text>

                   <Nodes>

                       <Node>

                            <Text>Sub Child #1</Text>

                            <Nodes>

                                 <Node>

                                     <Text>Sub Sub Child #1</Text>

                                </Node>

                            </Nodes>

                       </Node>

                   </Nodes>

              </Node>

         </Nodes>

     </Node>

</Nodes>

    

1 XML文档格式对照表

这里不妨给出一个XML文档生成程序,XML节点的索引基于文档对象模型(DOM)

      

/// <summary>

/// 将数据集转换为XML(根据父节点)

/// </summary>

/// <param name="dsSource">数据集</param>

/// <param name="strParentID">父节点ID</param>

/// <param name="iParentIndex">父节点索引(列号)</param>

/// <param name="iTagIndex">值索引(列号)</param>

/// <param name="iContentIndex">内容索引(列号)</param>

/// <returns>XML Document</returns>

public static XmlDocument DataSet2XML(DataSet dsSource,string strParentID,int iParentIndex,int iTagIndex,int iContentIndex)

         {

              System.Data.DataView dv = new DataView(dsSource.Tables[0]);

        

              dv.RowFilter = dsSource.Tables[0].Columns[iParentIndex].ColumnName+"= '"+strParentID+"'";

              XmlDocument objXmlDoc = new XmlDocument();

              objXmlDoc.LoadXml("<?xml version ='1.0' ?><TREENODES></TREENODES>");

              System.Xml.XmlNode objRootNode = objXmlDoc.SelectSingleNode("TREENODES");

              AddXmlNodebyParent(dsSource,"",iParentIndex,iTagIndex,iContentIndex,objRootNode,objXmlDoc);

              return objXmlDoc;

         }

 

/// <summary>

/// 根据父节点增加xml节点

/// </summary>

/// <param name="dsSource">数据集</param>

/// <param name="strParentID">父节点ID</param>

/// <param name="iParentIndex">父节点索引(列号)</param>

/// <param name="iTagIndex">值索引(列号)</param>

/// <param name="iContentIndex">内容索引(列号)</param>

/// <param name="objNode">当前节点</param>

/// <param name="objXmlDoc">当前xml文档</param>

private static void AddXmlNodebyParent(DataSet dsSource,string strParentID,int iParentIndex,int iTagIndex,int iContentIndex,System.Xml.XmlNode objNode,XmlDocument objXmlDoc)

         {

              System.Data.DataView dv = new DataView(dsSource.Tables[0]);

              dv.RowFilter = dsSource.Tables[0].Columns[iParentIndex].ColumnName+"= '"+strParentID+"'";//过滤出给定父节点的子节点

              foreach(System.Data.DataRowView drow in dv)

              {

                   //新节点

                   XmlElement objXmlElement = objXmlDoc.CreateElement("treenode");//创建一个<treenode>节点

                   objXmlElement.SetAttribute("text",drow[iContentIndex].ToString().Trim());//设置该节点text属性

                   objXmlElement.SetAttribute("tag",drow[iTagIndex].ToString().Trim());//设置该节点tag属性 

                   objNode.AppendChild(objXmlElement);

                   //再次递归

                   AddXmlNodebyParent(dsSource,drow[iTagIndex].ToString().Trim(),iParentIndex,iTagIndex,iContentIndex,objXmlElement,objXmlDoc);

              }

         }

 

有了生成的XML文档,构造Tree View则是相当简单的,在NetAdvantageTree View控件中只需利用自带的Load方法加载一下XML文档即可。从软件体系结构的角度来看,用于显示的Tree View控件在生成过程中只用到后台或远程传递过来XML文档(),无疑降低了耦合性。此外,一件有意义的工作就是设计XML到数据集的转换,得到具有本地结构的可操纵的数据集。

/// <summary>

/// 将数据集转换为XML(根据父节点)

/// </summary>

/// <param name="dsSource">数据集</param>

/// <param name="strParentID">父节点ID</param>

/// <param name="iParentIndex">父节点索引(列号)</param>

/// <param name="iTagIndex">值索引(列号)</param>

/// <param name="iContentIndex">内容索引(列号)</param>

/// <returns>XML Document</returns>

public static XmlDocument DataSet2XML(DataSet dsSource,string strParentID,int iParentIndex,int iTagIndex,int iContentIndex)

         {

              System.Data.DataView dv = new DataView(dsSource.Tables[0]);

        

              dv.RowFilter = dsSource.Tables[0].Columns[iParentIndex].ColumnName+"= '"+strParentID+"'";

              XmlDocument objXmlDoc = new XmlDocument();

              objXmlDoc.LoadXml("<?xml version ='1.0' ?><TREENODES></TREENODES>");

              System.Xml.XmlNode objRootNode = objXmlDoc.SelectSingleNode("TREENODES");

              AddXmlNodebyParent(dsSource,"",iParentIndex,iTagIndex,iContentIndex,objRootNode,objXmlDoc);

              return objXmlDoc;

         }

 

/// <summary>

/// 根据父节点增加xml节点

/// </summary>

/// <param name="dsSource">数据集</param>

/// <param name="strParentID">父节点ID</param>

/// <param name="iParentIndex">父节点索引(列号)</param>

/// <param name="iTagIndex">值索引(列号)</param>

/// <param name="iContentIndex">内容索引(列号)</param>

/// <param name="objNode">当前节点</param>

/// <param name="objXmlDoc">当前xml文档</param>

private static void AddXmlNodebyParent(DataSet dsSource,string strParentID,int iParentIndex,int iTagIndex,int iContentIndex,System.Xml.XmlNode objNode,XmlDocument objXmlDoc)

         {

              System.Data.DataView dv = new DataView(dsSource.Tables[0]);

              dv.RowFilter = dsSource.Tables[0].Columns[iParentIndex].ColumnName+"= '"+strParentID+"'";//过滤出给定父节点的子节点

              foreach(System.Data.DataRowView drow in dv)

              {

                   //新节点

                   XmlElement objXmlElement = objXmlDoc.CreateElement("treenode");//创建一个<treenode>节点

                   objXmlElement.SetAttribute("text",drow[iContentIndex].ToString().Trim());//设置该节点text属性

                   objXmlElement.SetAttribute("tag",drow[iTagIndex].ToString().Trim());//设置该节点tag属性 

                   objNode.AppendChild(objXmlElement);

                   //再次递归

                   AddXmlNodebyParent(dsSource,drow[iTagIndex].ToString().Trim(),iParentIndex,iTagIndex,iContentIndex,objXmlElement,objXmlDoc);

              }

         }

 

有了生成的XML文档,构造Tree View则是相当简单的,在NetAdvantageTree View控件中只需利用自带的Load方法加载一下XML文档即可。从软件体系结构的角度来看,用于显示的Tree View控件在生成过程中只用到后台或远程传递过来XML文档(),无疑降低了耦合性。此外,一件有意义的工作就是设计XML到数据集的转换,得到具有本地结构的可操纵的数据集。

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
调用示例:
string strXml = "<?xml version='1.0' encoding='utf-8' standalone='yes'?><Nodes><Node><Nodes><Node><Text>Child #1</Text><Tag>hhee</Tag><Nodes><Node><Text>Sub Child #1</Text></Node></Nodes></Node><Node><Text>Child #2</Text><Nodes><Node><Text>Sub Child #1</Text><Nodes><Node><Text>Sub Sub Child #1</Text></Node></Nodes></Node></Nodes></Node></Nodes></Node></Nodes>";
   
   this.UltraWebTree1.ReadXmlString(strXml,true,false);

(to be continued)