简体   繁体   English

Xml文件不适用于在C#中使用XDocument.Load的所有事件方法

[英]Xml file not available to all event methods using XDocument.Load in C#

I wanted to load an XML and have it available to all events. 我想加载XML并使其可用于所有事件。 In the application below, the Button1 and Button3 events use the loaded XML , whereas Button2 won't and I had to load it within the event. 在下面的应用程序中, Button1Button3事件使用加载的XML ,而Button2则不会,我不得不在事件内加载它。 I am assuming that every time I load the file it is taking up more resources, which I am trying to avoid. 我假设每次加载文件都会占用更多资源,而我试图避免这种情况。 My questions are: - Do I have to find a different way to populate the Datagridview ? 我的问题是:-我是否必须找到其他方法来填充Datagridview - Do I need to somehow unload the XML file if I need to load it somewhere else to save system resources. -如果需要将XML文件加载到其他地方以节省系统资源,是否需要以某种方式卸载XML文件。

I am new to programming and self taught so apologize in advance if terminology is not correct. 我是编程新手,自学成才,因此如果术语不正确,请提前道歉。

It is an application in a Windows form with: 它是Windows形式的应用程序,具有:

  • Button1 generating a listBox in ListBox1; Button1在ListBox1中生成一个listBox;
  • Button2 populating dataGridView1 with 2 columns; Button2用2列填充dataGridView1;
  • Button3 populating comboBox1 list Button3填充comboBox1列表

XML is as Follows: XML如下所示:

<?xml version="1.0" encoding="utf-8" ?>
<Config>  
  <Categories>
    <Category Name="OneChar">
      <Entry>
        <Name>a</Name>
        <id>1</id>
      </Entry>
      <Entry>
        <Name>b</Name>
        <id>2</id>
      </Entry>
      <Entry>
        <Name>c</Name>
        <id>3</id>
      </Entry>
    </Category>
    <Category Name="TwoChar">
      <Entry>
        <Name>aa</Name>
        <id>11</id>
      </Entry>
      <Entry>
        <Name>bb</Name>
        <id>22</id>
      </Entry>
      <Entry>
        <Name>cc</Name>
        <id>33</id>
      </Entry>      
    </Category>   
  </Categories>
  <Schemes>
  </Schemes>
</Config>

Code as Follows: 代码如下:

using System;
using System.Windows.Forms;
using System.Xml.Linq;
using System.Xml;
using System.Xml.XPath;

namespace List_box_multiple_query
{
    public partial class Form1 : Form
    {
        XDocument xdoc = XDocument.Load("Config\\TestFile.xml");
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            listBox1.Items.Clear();
            var result = xdoc.XPathSelectElements("/Config/Categories/Category [@Name='TwoChar']/Entry/Name");
            foreach (string entry in result)
            {
                listBox1.Items.Add(entry);
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {

            dataGridView1.Rows.Clear();
            dataGridView1.Refresh();

            XmlDocument doc = new XmlDocument();
            doc.Load("Config\\testfile.xml");
            XmlNodeList nodeList;
            XmlNode root = doc.DocumentElement;
            nodeList = root.SelectNodes("/Config/Categories/Category[@Name='OneChar']/Entry");

            foreach (XmlNode entry in nodeList)
            {               
                int n = dataGridView1.Rows.Add();
                dataGridView1.Rows[n].Cells[0].Value = entry["Name"].InnerText.ToString();
                dataGridView1.Rows[n].Cells[1].Value = entry["id"].InnerText.ToString();                
            }

        }

        private void button3_Click(object sender, EventArgs e)
        {
            var result = xdoc.XPathSelectElements("/Config/Categories/Category [@Name='TwoChar']/Entry/Name");

            foreach (string entry in result)
            {
                comboBox1.Items.Add(entry);
            }
        }
    }
}

First, you need to be consistently using XDocument or XmlDocument . 首先,您需要始终使用XDocument或XmlDocument

You can define a 您可以定义一个

 private Lazy<XmlDocument> docLazy = 
         new Lazy<XmlDocument>(() =>
             { 
                 XmlDocument doc = new XmlDocument();
                 doc.Load("Config\\TestFile.xml");
                 return doc;
             }
         );

and then use it in all the handlers 然后在所有处理程序中使用它

  var doc = docLazy.Value;

In this way it will be loaded from file only for the first call and then cached in memory. 这样,仅在第一次调用时才从文件中加载它,然后将其缓存在内存中。

My previous answer was similar but for XDocument. 我以前的答案与之类似,但针对XDocument。

reply to comments 回复评论

Is there an easy way to select nodes in an XML and use their contents...? 有没有一种简单的方法可以选择XML中的节点并使用其内容...?

Yes, for example 是的,例如

var test_nodeList  = xdoc.Descendants("Category")
    .Where(x => x.Attribute("Name").Value.Equals("OneChar"))
       .Descendants("Entry");

instead of 代替

nodeList = root.SelectNodes("/Config/Categories/Category[@Name='OneChar']/Entry");

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM