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 = "";
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(?:(?<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()));
}
}
It works but sometimes shows an exception that I can't figure out how to fix
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
Can someone help ??