从c#中的另一个文件更新节点内容?

时间:2017-09-29 14:49:09

标签: c# xml linq

我试图从另一个文件更新* .xml文件的节点内容。 文件夹结构的格式为Folder_structure

我想通过第一个节点标签的内容更改 xml 文件夹中xml文件的第一个节点标签位于 meta 文件夹中的xml文件。 以下是我尝试过的代码

using System;
using System.IO;
using System.Xml.Linq;
using System.Linq;
using System.Windows.Forms;
namespace XML_Parse
{
    /// <summary>
    /// Description of MainForm.
    /// </summary>
    public partial class MainForm : Form
    {
        public MainForm()
        {
            //
            // The InitializeComponent() call is required for Windows Forms designer support.
            //
            InitializeComponent();

            //
            // TODO: Add constructor code after the InitializeComponent() call.
            //
        }
        void Button1Click(object sender, EventArgs e)
        {
            if (folderBrowserDialog1.ShowDialog() == DialogResult.OK) {
                TextBox1.Text = folderBrowserDialog1.SelectedPath;
            }
        }

        void Button3Click(object sender, EventArgs e)
        {
            string targetDirectory1 = TextBox1.Text;
            string[] xmlDir = Directory.GetDirectories(targetDirectory1+@"\", "xml*", SearchOption.AllDirectories);
            string[] xmlFilesArray1 = Directory.GetFiles(xmlDir[0], "*.xml", SearchOption.AllDirectories);
            string[] xmlDir2 = Directory.GetDirectories(targetDirectory1+@"\", "meta*", SearchOption.AllDirectories);
            string[] xmlFilesArray2 = Directory.GetFiles(xmlDir[0], "*.xml", SearchOption.AllDirectories);


            foreach (string xmlFile in xmlFilesArray1)
            {
                var FileInfo1 = new FileInfo(xmlFile);
                string FileLocation1 = FileInfo1.FullName;
                string file_name = Path.GetFileName(FileLocation1);
                foreach (var xmlFile2 in xmlFilesArray2)
                {
                    if (xmlFile2.Contains(file_name))
                    {
                        string path = Path.GetFullPath(xmlFile2);
                        XDocument doc = XDocument.Load(path);
                        string name = doc.Root.Element("Employee").Element("label").Value;
                        XDocument doc2 = XDocument.Load(FileLocation1);
                        doc2.Root.Element("Employee").SetElementValue("label", name);
                        doc2.Save(FileLocation1);
                    }
                }
            }
            MessageBox.Show("Process complete");
        }
    }
}

但是我收到错误消息 System.IndexOutOfRangeException:索引超出了数组的范围。 注意:用户在TextBox1中给出的文件夹路径包含多个具有上述文件夹结构的文件夹,我想对具有上述文件夹结构的所有文件夹执行此操作。

2 个答案:

答案 0 :(得分:0)

首次使用xmlDir[0]是您获得例外的地方。上一行必须返回符合条件的0个目录。

在分配xmlDir并在调试器中启动的行上设置断点。当您跨过该线时,您将在xmlDir中看到零元素。您正尝试访问元素索引0处的项目(第一个元素),但没有,因此您获得IndexOutOfRangeException

最佳做法是在尝试访问第一个元素之前通过xmlDir.Length > 0xmlDir.Any()进行检查。

答案 1 :(得分:0)

试试这个

//get all directories from basepath 
       string[] filesindirectory = Directory.GetDirectories(basePath);


      //Loop through each parent directory and get each matching xml file from it
         List<string[]> newList = filesindirectory.Select(folder => (from item in Directory.GetDirectories(folder, "meta", SearchOption.AllDirectories)
                         .Select(item => Directory.GetFiles(item, "*.xml"))
                         .ToList()
                         .SelectMany(x => x)
                     let sx = Directory.GetDirectories(folder, "xml", SearchOption.AllDirectories)
                         .Select(items => Directory.GetFiles(items, "*.xml"))
                         .ToList()
                         .SelectMany(s => s)
                         .Any(s => Path.GetFileName(s) == Path.GetFileName(item))
                     where sx
                     select item).ToArray()
                 .Concat((from xmlItem in Directory.GetDirectories(folder, "xml", SearchOption.AllDirectories)
                         .Select(item => Directory.GetFiles(item, "*.xml"))
                         .ToList()
                         .SelectMany(xs => xs)
                     let sx = Directory.GetDirectories(folder, "meta", SearchOption.AllDirectories)
                         .Select(items => Directory.GetFiles(items, "*.xml"))
                         .ToList()
                         .SelectMany(sc => sc)
                         .Any(sc => Path.GetFileName(sc) == Path.GetFileName(xmlItem))
                     where sx
                     select xmlItem).ToArray()))
             .Select(xmlFiles => xmlFiles.ToArray()).ToList();


         //loop through each element of the jagged array
         foreach (string[] path in newList)
         {
             for (int j = 0; j < path.Length / 2; j++)
             {
                 XDocument doc = Xdocument.Load(path[j]);
                 string name = doc.Root.Element("Emp").Element("lbl").Value;
                 XDocument doc2 = Xdocument.Load(path[(path.Length / 2) + j]);
                 doc2.Root.Element("Employee").SetElementValue("label", name);
                 doc2.Save(path[(path.Length / 2) + j]);
             }
         }

归功于 JapanDave