Программа модификации атрибутов узлов показывает исключение..
Я пытаюсь создать программу, которая будет искать 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
Может кто-нибудь помочь ??