Member 12692000 Ответов: 1

Программа модификации атрибутов узлов показывает исключение..


Я пытаюсь создать программу, которая будет искать xml-файлы для узлов в форме <disp-formula id="deqnX-Y">, создайте словарь, где ключи похожи rid="deqnX" ... rid="deqnY", (где X увеличивается на +1 до тех пор, пока не достигнет Y) и их соответствующие аналоги значения подобны rid="deqnX-Y" каждый из них, то я могу просто сделать поиск и заменить с помощью словаря, чтобы изменить узлы ссылок. т. е. если файл имеет такие узлы, как <disp-formula id="deqn5-7">, <disp-formula id="deqn9-10">, <disp-formula id="deqn3a-3c">, <disp-formula id="deqn4p-5b"> и есть узлы связи в виде

<xref ref-type="disp-formula" rid="deqn5">
<xref ref-type="disp-formula" rid="deqn6">
<xref ref-type="disp-formula" rid="deqn10">
<xref ref-type="disp-formula" rid="deqn5c">

они должны быть изменены на

<xref ref-type="disp-formula" rid="deqn5-7">
<xref ref-type="disp-formula" rid="deqn5-7">
<xref ref-type="disp-formula" rid="deqn9-10">
<xref ref-type="disp-formula" rid="deqn4p-5b">

Я также хочу, чтобы программа игнорировала такие узлы, как <disp-formula id="deqn5-7c"> и-или <disp-formula id="deqn2a-4"> в файле.

Сейчас я использую приведенный ниже код

Что я уже пробовал:

void Button1Click(object sender, EventArgs e)
			
		{
			string active_filename = "";
			try
			{
				string[] path = Directory.GetDirectories(textBox1.Text, "xml", SearchOption.AllDirectories)
					.SelectMany(x => Directory.GetFiles(x, "*.xml", SearchOption.AllDirectories)).ToArray();
				Dictionary<string, string> dict = new Dictionary<string, string>();
				//var re = new Regex(@"deqn(\d+)-(\d+)");
				var re=new Regex("deqn(?:(?<match1>\\d+)-(?<match2>\\d+)|(?<match1>\\d+\\w+)-(?<match2>\\d+\\w+))\\b");
				foreach (var file in path)
				{
					dict.Clear();
					active_filename = file;
					XDocument doc = XDocument.Load(file, LoadOptions.PreserveWhitespace);
					IEnumerable<XAttribute> list_of_elements = doc.Descendants("disp-formula").Where(z => (z.Attribute("id") != null) && re.IsMatch(z.Attribute("id").Value)).Attributes("id");
					foreach (XAttribute ele in list_of_elements)
					{
						if (Regex.IsMatch(re.Match(ele.Value).Groups["match1"].Value, @"^\d+$") && Regex.IsMatch(re.Match(ele.Value).Groups["match2"].Value, @"^\d+$"))
						{
							var from = int.Parse(re.Match(ele.Value).Groups["match1"].Value);
							var to = int.Parse(re.Match(ele.Value).Groups["match2"].Value);
							for (int i = from; i <= to; i++)
								dict.Add("rid=\"deqn" + i + "\"", "rid=\"" + ele.Value + "\"");
						}
						if (Regex.IsMatch(re.Match(ele.Value).Groups["match1"].Value, @"^\d+[a-z]$") && Regex.IsMatch(re.Match(ele.Value).Groups["match2"].Value, @"^\d+[a-z]$"))
						{
							var from = re.Match(ele.Value).Groups["match1"].Value;
							var to = re.Match(ele.Value).Groups["match2"].Value;
							char startCharacter = from.Substring(from.Length - 1)[0];
							char endCharacter = to.Substring(to.Length - 1)[0];
							int startNumber = int.Parse(from.Substring(0, from.Length - 1));
							int endNumber = int.Parse(to.Substring(0, to.Length - 1));
							string alphabet = "abcdefghijklmnopqrstuvwxyz";
							for (int i = startNumber; i <= endNumber; ++i)
							{
								int currentCharEnd =
									(i == endNumber) ? alphabet.IndexOf(endCharacter) : alphabet.Length - 1;
								for (int j = alphabet.IndexOf(startCharacter); j <= currentCharEnd; ++j)
								{
									dict.Add("rid=\"deqn" + i.ToString() + alphabet[j] + "\"",
									         "rid=\"deqn" + from.ToString() + "-" + to.ToString() + "\"");
								}
								startCharacter = 'a';
							}
						}
						foreach (KeyValuePair<string, string> element in dict)
						{
							string text = File.ReadAllText(file);
							text = text.Replace(element.Key, element.Value);
							File.WriteAllText(file, text);
						}
					}
				}
				MessageBox.Show("Done");
			}
			catch (Exception ex)
			{
				
				MessageBox.Show(string.Format(@"Error in file ({0}), below are the debug details: {1}", active_filename, ex.StackTrace.ToString()));
			}
		}

Это работает, но иногда показывает исключение, которое я не могу понять, как исправить

System.IO.IOException occurred
  HResult=0x800704C8
  Message=The requested operation cannot be performed on a file with a user-mapped section open.

  Source=mscorlib
  StackTrace:
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
   at System.IO.StreamWriter.CreateFile(String path, Boolean append, Boolean checkHost)
   at System.IO.StreamWriter..ctor(String path, Boolean append, Encoding encoding, Int32 bufferSize, Boolean checkHost)
   at System.IO.File.InternalWriteAllText(String path, String contents, Encoding encoding, Boolean checkHost)
   at System.IO.File.WriteAllText(String path, String contents)
   at test.Form1.button1_Click(Object sender, EventArgs e) in C:\Users\Yyyy\source\repos\WindowsFormsApp\test\Form1.cs:line 82
   at System.Windows.Forms.Control.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ButtonBase.WndProc(Message& m)
   at System.Windows.Forms.Button.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
   at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
   at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
   at System.Windows.Forms.Application.Run(Form mainForm)
   at test.Program.Main() in C:\Users\Yyyy\source\repos\WindowsFormsApp4\test\Program.cs:line 19

Может кто-нибудь помочь ??

1 Ответов

Рейтинг:
1

Dirk Bahle

Похоже, что ваш файл просматривается другим инструментом, например Visual Studio, Internet Explorer или другим редактором.

Дважды убедитесь, что ни одно другое программное обеспечение не имеет открытого файла XML:
1) скомпилировать проект
2> перезагрузите компьютер
3> Start Executable -> Вы все еще можете воспроизвести для этого случая?


Member 12692000

да, проблема все еще существует, она отображается на части кода File.WriteAllText(file, text);

Dirk Bahle

Хорошо, убедитесь, что это не проводник с его панелью предварительного просмотра (используйте ярлык для запуска теста после перезагрузки).

Если это не так, исследуйте в другом направлении, ваша программа должна блокировать ваш собственный доступ, поставить точку останова или аналогичную защиту - везде, где вы открываете файл - должно быть событие или процесс, который вы иногда делаете более одного раза, и он иногда производит эту блокировку, не так ли?