【问题标题】:How to display a large XML file (>21MB) in a tree view quickly如何在树视图中快速显示大型 XML 文件 (>21MB)
【发布时间】:2015-05-15 04:18:22
【问题描述】:

我需要在 C# Windows 窗体应用程序的树视图控件中显示一个大型 XML 文件 (>21MB)。我已经编写了适用于小型 XML 文件的代码,但是当我试图打开一个 BIG XML 文件(> 1 MB)时,它花费了太多时间。 任何人都可以建议我如何优化这一点并建议我进行任何更改或替代方案来实现这一点。

下面是sn-p的代码:

private void CreateTreeViewFromATXML(string strSrcFileName)
        {
            XmlDataDocument xmldoc = new XmlDataDocument();
            XmlNode xmlnode ;
            FileStream fs = new FileStream(strSrcFileName, FileMode.Open, FileAccess.Read);
            xmldoc.Load(fs);
            xmlnode = xmldoc.ChildNodes[1];
            XMLTreeView.Nodes.Clear();
            XMLTreeView.Nodes.Add(new TreeNode(xmldoc.DocumentElement.Name));
            TreeNode tNode ;
            tNode = XMLTreeView.Nodes[0];
            AddNode(xmlnode, tNode);
        }


    private void AddNode(XmlNode inXmlNode, TreeNode inTreeNode)
    {
        //XmlNode xNode ;
        TreeNode tNode ;
        XmlNodeList nodeList ;
        int i = 0;
        if (inXmlNode.HasChildNodes)
        {
            nodeList = inXmlNode.ChildNodes;

            foreach (XmlNode XNode in inXmlNode.ChildNodes)
            {
                tNode = new TreeNode(XNode.Name);
                inTreeNode.Nodes.Add(tNode);
                AddNode(XNode, tNode);
            }
        }
        else
        {
            inTreeNode.Text = inXmlNode.InnerText.ToString();
        }
    }

【问题讨论】:

  • 不是预先构建整个树视图,而是懒惰地构建它。当用户点击一个节点时,构建它的子节点。
  • 我还会考虑使用工作线程/后台线程来解析和生成树节点,因为不希望像这样锁定处理大量数据的 UI 线程。

标签: c# xml treeview xmlreader


【解决方案1】:

我会这样包装你的代码:

XMLTreeView.BeginUpdate();
try
{
    CreateTreeViewFromATXML(strSrcFileName);
}
catch (Exception e)
{
    //Handle any error
}
finally
{
    XMLTreeView.EndUpdate();
}

如果您不在更新块中,它会在每个添加节点时重新绘制 GUI,这很昂贵。您在AddNode 中也有递归,但如果 XML 嵌套不是太深,这应该不是问题。

【讨论】:

    【解决方案2】:

    我建议使用 XDocument 和 XML to Linq 进行更快的解析。您可以使用以下代码来解析 XML:

    using System.Xml;
    using System.Xml.Linq;
    using System.Data;
    
                XDocument xdoc = XDocument.Load(XMLFile);
    
    var item = from items in xdoc.Element("EPICORTLOG").Descendants("POS")
                           where (string)items.Element("Id") == strSelectedPOSID
                           select items.Elements("TRADE").Elements("ITEM").ToList().ToList();
    

    然后您可以按照以下链接中的说明来解析 XML: http://www.dotnetcurry.com/showarticle.aspx?ID=564 上面的文章将解释 XML to LINQ 编程。使用上述方法,您可以在短时间内加载最大 10MB 的 XML 文件。

    【讨论】:

      【解决方案3】:

      最近,我使用 TreeView 组件在 C# 中实现了我的 HTML 编辑器,我使用序列化数据结构来提高打开和保存 XML 文件的性能。 根据我的经验,使用这种结构并序列化读写文件可以在我的计算机中在 2 秒内打开高达 20M 字节的文件。此解决方案可以在我的 C# 应用程序中打开超过 2G 字节的 XML 文件。希望这个解决方案可以更好地帮助你。

      为 TreeView 和 TreeNode 定义可序列化结构的示例

      [Serializable]
      public class TreeViewData
      {
          public TreeNodeData[] Nodes;
          public TreeViewData(){ }  
          public TreeViewData(TreeView treeview)
          {
             //your code
          }
          public TreeViewData(TreeNode treenode)
          {
             //your code 
          }
          public void PopulateTree(TreeView treeview)
          {
              //your code 
          }
          public void PopulateSubTree(TreeNode treenode)
          {
               //your code 
          }
      }
      [Serializable]
      public class TreeNodeData
      {
          public string Text;
          public int ImageIndex;
          public int SelectedImageIndex;
          public string Tag;
          public TreeNodeData[] Nodes;
          public TreeNodeData() {}  
          public TreeNodeData(TreeNode node)
          {
                // your code 
          }
          public TreeNode ToTreeNode()
          {
           // your code 
          }
      }
      

      序列化读取 XML 文件的示例

      System.Xml.Serialization.XmlSerializer ser = new System.Xml.Serialization.XmlSerializer(typeof(TreeViewData));
      System.IO.FileStream file = new System.IO.FileStream(strFilename, FileMode.Open);
      System.Xml.XmlTextReader reader = new System.Xml.XmlTextReader(file);
      TreeViewData treeData = (TreeViewData)ser.Deserialize(reader);
      treeData.PopulateTree(TreeView1);
      

      序列化写入XML文件的示例

      System.Xml.Serialization.XmlSerializer ser = new System.Xml.Serialization.XmlSerializer(typeof(TreeViewData));
      System.IO.FileStream file = new System.IO.FileStream(strFilename,   System.IO.FileMode.Create);
      System.Xml.XmlTextWriter writer = new System.Xml.XmlTextWriter(file, null);
      ser.Serialize(writer, new TreeViewData(TreeView1));
      

      【讨论】:

      • 其实我也想问和你一样的问题。但我的问题是如何在树视图中显示超过 1G 字节的大型 xml 文件。这就是我找到你的帖子的原因。
      猜你喜欢
      • 2018-09-21
      • 1970-01-01
      • 2022-06-17
      • 1970-01-01
      • 2019-01-15
      • 2021-10-06
      • 1970-01-01
      • 2018-04-03
      • 2021-01-01
      相关资源
      最近更新 更多