根据需要使用XML中的数据填充TreeView

时间:2010-02-25 21:20:41

标签: asp.net xml treeview

我有一个大型XML文件(3000多个节点),我希望在ASP.NET上的TreeView中表示。我无法将其数据绑定到XMLDataSource,因为加载TreeView会变得太慢(我从来没有等过足够长的时间看它完成......)

因此,解决方案是使用TreeNodes的PopulateOnDemand属性仅在需要时加载数据。问题是,我想不出一种方法来实现这个......

如何根据节点的ID搜索XMLDocument以获取具有此ID的节点的所有子节点?

XML看起来像这样:

<document ID=1>
    <document ID=2>
        <document ID=3>
        </document>
    </document>
    <document ID=4>
    </document>
</document>

关于它可以降低多少级别或其他任何级别也没有规则......

2 个答案:

答案 0 :(得分:2)

根据我自己的经验,在ASP.NET树视图中添加3000个节点是件坏事,因为视图状态会变得狂暴......意味着它会爆炸并变得真的大!

尝试使用客户端Javascript(例如使用JQuery)和AJAX请求来加速加载。使用MVC和客户端Javascript也可以是一个选项。

同样根据经验,不要使用MS Ajax来更新树视图,不支持它。

对于阅读XML,Linq to XML可能是一个快速查询的选项。 Here你可以找到一个样本。

如果必须使用System.Xml,则以下代码从文档中获取给定id的子项:

  XmlDocument document = new XmlDocument();
  XmlNodeList nodes = document.SelectNodes(string.Format("/descendant-or-self::*[@id = '{0}']/*", id));
  foreach (XmlNode child in nodes) {
    // child contains the child node
  }

当你没有命名空间时,这很好用,否则,它会有点乱。

使用Linq to XML,整个事情看起来像这样:

XDocument doc = new XDocument();
XElement root = doc.Root;
IEnumerable<XElement> children = doc.Root
                                    .DescendantsAndSelf()
                                    .Where(x => (string) x.Attribute("id") == id)
                                    .SelectMany(x => x.Elements());
foreach (var child in children) {
   // do something with the child
}

答案 1 :(得分:0)

要查找所需的节点,请递归搜索树,其中启动节点的位置为xmlDoc.DocumentElement。

public XmlNode FindNode( XmlNode node, string id ) {
  XmlNode fNode = null;

  if ( node != null ) {
    bool bfind = id == node.Attributes.GetNamedItem( "Id" ).Value; // here is where you put your matching criteia

    if ( bfind  )
      return node;

    XmlNodeList nodeList = node.ChildNodes;
    int length = node.ChildNodes.Count;

    XmlNode childNode = null;
    int index = 0;
    do {
      childNode = nodeList.Item( index++ );
      fNode = FindNode( childNode, Name );
    } while ( childNode != null && fNode == null );
  }
  return fNode;
}

获得节点后,您可以使用node.NextSibling获取所有兄弟节点