Click here to Skip to main content
15,905,781 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I'm trying to create a program which will search the xml files for nodes in the form <disp-formula id="deqnX-Y">, create a dictionary where key's are like rid="deqnX" ... rid="deqnY", (where X is incremented by +1 till it reaches Y) and their respective value counterparts are like rid="deqnX-Y" each, Then I can simply do a search and replace using the dictionary to change the link nodes. i.e. if the file has nodes like <disp-formula id="deqn5-7">, <disp-formula id="deqn9-10">, <disp-formula id="deqn3a-3c">, <disp-formula id="deqn4p-5b"> and there are link nodes in the form

<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">

they should be changed to

<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">

I also want the program to ignore nodes like <disp-formula id="deqn5-7c"> and/or <disp-formula id="deqn2a-4"> in the file.

I'm using the below code for now

What I have tried:

void Button1Click(object sender, EventArgs e)
			string active_filename = "";
				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)
					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);
			catch (Exception ex)
				MessageBox.Show(string.Format(@"Error in file ({0}), below are the debug details: {1}", active_filename, ex.StackTrace.ToString()));

It works but sometimes shows an exception that I can't figure out how to fix

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

   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

Can someone help ??
Updated 9-Feb-18 2:17am

1 solution

It looks your file is looked by another tool e.g. Visual Studio, Internet Explorer or other editor.

Make double sure that no other software has the XML file open:
1) Compile the project
2> Reboot computer
3> Start Executable -> Can you still reproduce for this case?
Share this answer
Member 12692000 9-Feb-18 8:23am    
yes, the problem is still there, its showing on the code portion File.WriteAllText(file, text);
Dirk Bahle 9-Feb-18 14:26pm    
OK, make sure its not the Explorer with its Preview pane (use a shortcut to start your test after reboot).

If thats not it, investigate into the other direction, your program must be blocking your own access, put a breakpoint or similar guard - everywhere you open the file - there must be an event or process you are sometimes doing more than once and it sometimes produces this lock, right?

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900