I have an requirement to read the SGML file and replace if the symbol like comma(,) or full stop (.) then I need to change the symbols and save with the same SGML file itself but I am facing the format issue after replacing the content.
Below is my code and my final output would be store with the same .sgm format.
The below code is working but after replacing the values the output format is differs. Can you suggest for this scenario
Main method:
string resultValue = HTMLToEntity(ReplaceSGML(sbContent.ToString()));
StringReader sr = new StringReader(resultValue.ToString());
SgmlReader reader = new SgmlReader();
reader.WhitespaceHandling = WhitespaceHandling.All;
reader.CaseFolding = Sgml.CaseFolding.ToLower;
reader.InputStream = sr;
StringWriter sw = new StringWriter();
XmlTextWriter w = new XmlTextWriter(sw);
w.Formatting = System.Xml.Formatting.Indented;
w.WriteStartDocument();
reader.Read();
while (!reader.EOF)
{
w.WriteNode(reader, true);
}
//File.WriteAllText(#"C:\Output\test.sgm", );
w.Flush();
w.Close();
Method : ReplaceSGML
private static string ReplaceSGML(string html)
{
XmlDocument xml = new XmlDocument();
xml.Load(_xmlEnglishPath);
XmlNodeList resources = xml.SelectNodes("root/data");
_htmlEnglishDictonaries = new Dictionary<string, string>();
_htmlEnglishDictonaries.Add(";", "{After1Space}"); // replacing semicolon into {After1space}
_htmlEnglishDictonaries.Add(":", "{Before1Space}"); // replacing colon into {Before1Space}
_htmlEnglishDictonaries.Add(".", "{Before1Space}"); // replacing . into {Before1Space}
string line = string.Empty;
StringReader reader = new StringReader(html);
while (reader.Peek() > -1)
{
line = reader.ReadLine();
foreach (var events in _htmlEnglishDictonaries)
{
if (line.Contains(events.Key))
{
// Rule should be implement
// <!-- Replacetext 1.{After1Space}, 2.{Before1Space}, 3.{NoSpace}, 4. {After1LetterCaps} -->
int idx;
if (events.Value.ToLower().Trim() == "{after1space}")
{
idx = line.IndexOf(events.Key) + events.Key.Length;
if (line[idx].ToString() != " ")
{
line = line.Replace(events.Key, events.Key + " ");
}
}
if (events.Value.ToLower().Trim() == "{before1space}")
{
idx = line.IndexOf(events.Key);
if (line[idx].ToString() != " ")
{
line = line.Replace(events.Key, " " + events.Key);
}
}
if (events.Value.ToLower().Trim() == "{before1space},{after1space}")
{
idx = line.IndexOf(events.Key);
if (line[idx].ToString() != " ")
{
line = line.Replace(events.Key, " " + events.Key + " ");
}
}
if (events.Value.ToLower().Trim() == "{nospace}")
{
idx = line.IndexOf(events.Key);
if (line[idx].ToString() != " ")
{
line = line.Replace(events.Key, " " + events.Key);
}
}
if (events.Value.ToLower().Trim() == "{after1lettercaps}")
{
idx = line.IndexOf(events.Key) + events.Key.Length;
if (line[idx].ToString() != " ")
{
if (line[idx + 1].ToString() != " ")
{
line = line.Replace(events.Key, " " + events.Key + line[idx + 1].ToString().ToUpper());
}
else
{
line = line.Replace(events.Key, " " + events.Key);
}
}
}
}
}
}
return line.ToString();
}
Thanks in advance
Related
if (GUILayout.Button("Copy settings"))
{
var selection = Selection.gameObjects.ToList();
for (int i = selection.Count - 1; i >= 0; --i)
{
var selected = selection[i];
WriteDataToFile("Transform " + i.ToString() + " Name ==> " + selected.name);
WriteDataToFile("************************" +
"********************");
if (selected.transform.parent != null)
WriteDataToFile(selected.transform.parent.ToString());
WriteDataToFile("local position " + selected.transform.localPosition.ToString());
WriteDataToFile("local rotation " + selected.transform.localRotation.ToString());
WriteDataToFile("local scale " + selected.transform.localScale.ToString());
WriteDataToFile("************************" +
"********************");
WriteDataToFile(" ");
}
}
And the WriteDataToFile:
private void WriteDataToFile(string line)
{
string path = "Assets/Resources/test.txt";
StreamWriter writer = new StreamWriter(path, true);
writer.WriteLine(line);
writer.Close();
}
First I want to check that if I click more then once on the button and it's the same data: name position rotation scale don't write again.
Second how can I read back the lines of the data and assign them into a object ? Also the name. So a new object will be created in the same name parent if the original was parent position rotation and scale.
This is how I'm reading now:
void ReadString()
{
string path = "Assets/Resources/test.txt";
StreamReader reader = new StreamReader(path);
Debug.Log(reader.ReadToEnd());
reader.Close();
}
To add new data to the file that doesn't already exist:
private void WriteDataToFile(string line)
{
string path = "Assets/Resources/test.txt";
string[] text = new string[];
if(File.Exists(path))
{
text = File.ReadAllLines(path);
if(!text.Contains(line))
File.AppendAllText(path, Line);
}
}
If you are not limited to using a text file for storing and retrieving data then I recommend finding a way to write all this data:
WriteDataToFile("Transform " + i.ToString() + " Name ==> " + selected.name);
WriteDataToFile("************************" +
"********************");
if (selected.transform.parent != null)
WriteDataToFile(selected.transform.parent.ToString());
WriteDataToFile("local position " + selected.transform.localPosition.ToString());
WriteDataToFile("local rotation " + selected.transform.localRotation.ToString());
WriteDataToFile("local scale " + selected.transform.localScale.ToString());
WriteDataToFile("************************" +
"********************");
WriteDataToFile(" ");
in less writes because opening and closing the file could be expensive. Maybe something like this:
var selected = selection[i].transform;
string toWrite = $"{parent}:{localPosition}:{localRotation}:{localScale}";
WriteDataToFile(toWrite);
This would mean retrieval would be simply - (not sure the type)
private gameObject GetObjectFromFile(Path, Id)
{
string[] text = new string[];
if(File.Exists(path))
{
text = File.ReadAllLines(path);
foreach(string s in text)
{
if(s.Split(':')[0] == Id.ToString())
{
text = s.Split(':');
break;
}
}
var Id = Convert.ToInt32(text[0]);
var localPosition = Convert.ToInt32(text[1]);
var localRotation = Convert.ToInt32(text[2]);
var localScale = Convert.ToInt32(text[3]);
return new gameObject(Id, localPosition, localRotation, localScale);
}
So, I am trying to create a file at a specific path but the code I have doesn't allows me to create folders.
This is the code I have:
public void LogFiles()
{
string data = string.Format("LogCarga-{0:yyyy-MM-dd_hh-mm-ss}.txt", DateTime.Now);
for (int linhas = 0; linhas < dataGridView1.Rows.Count; linhas++)
{
if (dataGridView1.Rows[linhas].Cells[8].Value.ToString().Trim() != "M")
{
var pathWithEnv = #"%USERPROFILE%\AppData\Local\Cargas - Amostras\_logs\";
var filePath = Environment.ExpandEnvironmentVariables(pathWithEnv);
using (FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate))
{
using (StreamWriter writer = File.AppendText(filePath + data))
{
string carga = dataGridView1.Rows[linhas].Cells[0].Value.ToString();
string referencia = dataGridView1.Rows[linhas].Cells[1].Value.ToString();
string quantidade = dataGridView1.Rows[linhas].Cells[2].Value.ToString();
string dataemissao = dataGridView1.Rows[linhas].Cells[3].Value.ToString();
string linha = dataGridView1.Rows[linhas].Cells[4].Value.ToString();
string marca = dataGridView1.Rows[linhas].Cells[5].Value.ToString().Trim();
string descricaoweb = dataGridView1.Rows[linhas].Cells[6].Value.ToString().Trim();
string codprod = dataGridView1.Rows[linhas].Cells[7].Value.ToString().Trim();
string tipoemb = dataGridView1.Rows[linhas].Cells[8].Value.ToString().Trim();
string nomepc = System.Environment.MachineName;
writer.WriteLine(carga + ", " + referencia + ", " + quantidade + ", " + dataemissao + ", " + linha + ", " + marca + ", " + descricaoweb + ", " + codprod + ", "
+ tipoemb + ", " + nomepc);
}
}
}
}
}
This %USERPROFILE%\AppData\Local\ in the universal path and I want to automatically create the \Cargas - Amostras\_logs\.
Do you have any idea how to do it?
The simpelest solution is replace
using (FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate))
with
System.IO.Directory.CreateDirectory(filePath)
That will create the directory if it does not exist or do nothing if it does.
You need to create two checks, for your first folder and then second directory.
var pathWithEnv = #"%USERPROFILE%\AppData\Local\Cargas - Amostras\";
if (System.IO.Directory.Exists(pathWithEnv))
{
pathWithEnv = System.IO.Path.Combine(pathWithEnv, #"_logs\");
if (System.IO.Directory.Exists(pathWithEnv))
{
//Do what you want to do, both directories are found.
}
else
{
System.IO.Directory.CreateDirectory(pathWithEnv);
//Do what you want to do, both directories are available.
}
}
else
{
System.IO.Directory.CreateDirectory(pathWithEnv);
pathWithEnv = System.IO.Path.Combine(pathWithEnv, #"_logs\");
if (System.IO.Directory.Exists(pathWithEnv))
{
//Do what you want to do, both directories are available now.
}
else
{
System.IO.Directory.CreateDirectory(pathWithEnv);
//Do what you want to do, both directories are created.
}
}
I want to set "
" to Xml file.But my below chord Unintentionally changed \n.
Can I set "
" in XML File?
please teach me.
foreach (XmlNode xnode in secondNode)
{
if (xnode.NodeType == XmlNodeType.Element && xnode.Name == "element")
{
string line1 = model.Second.CommentList[j].Line1;
string line2 = model.Second.CommentList[j].Line2;
if (string.IsNullOrEmpty(line2))
{
xnode.InnerXml = line1;
}
else
{
xnode.InnerXml = line1 + "
" + line2;
}
j++;
}
}
var outputStream = new MemoryStream();
outputStream.Position = 0;
using (XmlWriter xw = XmlWriter.Create(outputStream))
{
doc.WriteTo(xw);
}
outputStream.Flush();
outputStream.Position = 0;
I'm developing an application that reads a xml file folder , and each file it to do some checks and copied to a new folder based on some criteria.
But memory usage continues to grow when it arrives in the foreach loop , and I believe that should not happen , because the variables do not increase at each iteration , are only overwritten.
Here is my code:
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using System.Xml;
namespace XMLOrganizer
{
public partial class Form1 : Form
{
string selectedFolder;
public Form1()
{
InitializeComponent();
comboBox1.DropDownStyle = ComboBoxStyle.DropDownList;
comboBox1.SelectedIndex = 0;
}
private void button1_Click(object sender, EventArgs e)
{
folderBrowserDialog1.ShowDialog();
selectedFolder = folderBrowserDialog1.SelectedPath;
organizeBtn.Enabled = true;
}
private void organizeBtn_Click(object sender, EventArgs e)
{
if (comboBox1.SelectedIndex == -1)
{
MessageBox.Show("Selecione o tipo de nota", "Erro!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation,
MessageBoxDefaultButton.Button1);
return;
}
if (comboBox1.SelectedIndex != 2)
{
OrganizeXml(label2, selectedFolder, comboBox1);
}
//ORGANIZAR LOTES
else
{
string folder = selectedFolder;
label2.Text = "Arquivos sendo processados, aguarde...";
label2.Refresh();
string[] files = Directory.GetFiles(folder, "*.xml", SearchOption.AllDirectories);
int atualFile = 1, totalXML = files.Length;
foreach (string file in files)
{
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load(file);
XmlNodeList enviNFe = xmlDocument.GetElementsByTagName("enviNFe");
string versao = ((XmlElement)enviNFe[0]).Attributes["versao"].Value;
XmlNodeList NFe = ((XmlElement)enviNFe[0]).GetElementsByTagName("NFe");
Directory.CreateDirectory(selectedFolder + #"\NOTAS");
label2.Text = "Processando arquivo " + atualFile + " de " + totalXML;
string notaXML;
foreach (XmlElement nota in NFe)
{
notaXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><nfeProc versao=\"" + versao + "\" xmlns=\"http://www.portalfiscal.inf.br/nfe\">" + nota.OuterXml + "</nfeProc>";
XmlNodeList infNFe = nota.GetElementsByTagName("infNFe");
string chave = infNFe[0].Attributes["Id"].Value.Replace("NFe", "");
File.WriteAllText(selectedFolder + "\\NOTAS\\" + chave + ".xml", notaXML);
}
}
OrganizeXml(label2, selectedFolder + "\\NOTAS", comboBox1);
}
}
private static void OrganizeXml(Label label2, string selectedFolder, ComboBox comboBox1)
{
string folderMove = String.Empty;
string folder = selectedFolder;
label2.Text = "Arquivos sendo processados, aguarde...";
label2.Refresh();
string[] files = Directory.GetFiles(folder, "*.xml", SearchOption.AllDirectories);
int i = 1, arquivos = files.Length;
Directory.CreateDirectory(folder + #"\ORGANIZADO");
if (comboBox1.SelectedIndex != 2)
{
Directory.CreateDirectory(folder + #"\ORGANIZADO\OUTROS");
Directory.CreateDirectory(folder + #"\ORGANIZADO\LOTES");
}
foreach (string file in files)
{
XmlDocument xmlDocument = new XmlDocument();
try
{
xmlDocument.Load(file);
if (xmlDocument.DocumentElement.Name != "nfeProc")
{
XmlNodeList NFe = xmlDocument.GetElementsByTagName("NFe");
var nota = ((XmlElement) NFe[0]);
if (nota != null)
{
XmlNodeList infNFe = ((XmlElement) NFe[0]).GetElementsByTagName("infNFe");
string chave = infNFe[0].Attributes["Id"].Value.Replace("NFe", "");
string versao = infNFe[0].Attributes["versao"].Value;
string notaXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><nfeProc versao=\"" + versao +
"\" xmlns=\"http://www.portalfiscal.inf.br/nfe\">" + nota.OuterXml +
"</nfeProc>";
string dirNote = Path.GetDirectoryName(file);
File.WriteAllText(dirNote + "\\fix_" + chave + ".xml", notaXML);
}
}
//
//
//
}
catch (XmlException)
{
XmlDocument doc = new XmlDocument();
string arquivo = ReadFileToString(file);
arquivo = RemoveSpecialCharacters(arquivo);
if (arquivo == "")
{
File.Move(file, folder + #"\ORGANIZADO\OUTROS\corrupt_" + Path.GetFileName(file));
continue;
}
try
{
doc.LoadXml(arquivo);
doc.PreserveWhitespace = true;
doc.Save(file);
}
catch (XmlException)
{
File.Move(file, folder + #"\ORGANIZADO\OUTROS\corrupt_" + Path.GetFileName(file));
files = files.Where(f => f != file).ToArray();
}
}
}
foreach (string file in files)
{
string arquivoLoad = file;
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load(arquivoLoad);
XmlNodeList NFe = xmlDocument.GetElementsByTagName("NFe");
XmlNodeList enviNFe = xmlDocument.GetElementsByTagName("enviNFe");
if (NFe.Count == 0)
{
if (File.Exists(folder + #"\ORGANIZADO\OUTROS\no_NFe_" + Path.GetFileName(arquivoLoad)))
{
Random rnd = new Random();
File.Copy(arquivoLoad,
folder + #"\ORGANIZADO\OUTROS\no_NFe_" + rnd.Next(1, 5000) + Path.GetFileName(arquivoLoad));
}
else
{
File.Copy(arquivoLoad, folder + #"\ORGANIZADO\OUTROS\no_NFe_" + Path.GetFileName(arquivoLoad));
}
continue;
}
XmlNodeList infNFe = ((XmlElement)NFe[0]).GetElementsByTagName("infNFe");
string chave = infNFe[0].Attributes["Id"].Value.Replace("NFe", "");
if (xmlDocument.DocumentElement.Name != "nfeProc")
{
File.Move(arquivoLoad, folder + #"\ORGANIZADO\OUTROS\no_nfeProc_" + Path.GetFileName(arquivoLoad));
arquivoLoad = Path.GetDirectoryName(file) + "\\fix_" + chave + ".xml";
}
if (enviNFe.Count > 0)
{
if (File.Exists(folder + #"\ORGANIZADO\LOTES\" + Path.GetFileName(arquivoLoad)))
{
Random rnd = new Random();
File.Copy(arquivoLoad, folder + #"\ORGANIZADO\LOTES\" + rnd.Next(1, 5000) + Path.GetFileName(arquivoLoad));
}
else
{
File.Copy(arquivoLoad, folder + #"\ORGANIZADO\LOTES\" + Path.GetFileName(arquivoLoad));
}
continue;
}
//XmlNodeList infNFe = ((XmlElement)NFe[0]).GetElementsByTagName("infNFe");
XmlNodeList ide = ((XmlElement)infNFe[0]).GetElementsByTagName("ide");
string tpNF = ((XmlElement)ide[0]).GetElementsByTagName("tpNF")[0].InnerText;
//if (tpNF == "0") continue;
XmlNodeList emit = ((XmlElement)infNFe[0]).GetElementsByTagName("emit");
string emitInfoCod;
if (((XmlElement)emit[0]).GetElementsByTagName("CNPJ").Count > 0)
{
emitInfoCod = ((XmlElement)emit[0]).GetElementsByTagName("CNPJ")[0].InnerText;
}
else if (((XmlElement)emit[0]).GetElementsByTagName("CPF").Count > 0)
{
emitInfoCod = ((XmlElement)emit[0]).GetElementsByTagName("CPF")[0].InnerText;
}
else
{
emitInfoCod = "0";
}
string ide_dEmi = (((XmlElement)ide[0]).GetElementsByTagName("dEmi").Count > 0)
? ((XmlElement)ide[0]).GetElementsByTagName("dEmi")[0].InnerText
: ((XmlElement)ide[0]).GetElementsByTagName("dhEmi")[0].InnerText;
string[] data = ide_dEmi.Split('-');
string folderName = data[0] + "\\" + data[1];
string organizeStyle = String.Empty;
if (comboBox1.SelectedIndex == 0 || comboBox1.SelectedIndex == 2)
{
organizeStyle = folder + #"\ORGANIZADO\" + emitInfoCod + #"\" + folderName;
}
else
{
organizeStyle = folder + #"\ORGANIZADO\" + folderName + #"\" + emitInfoCod;
}
if (!Directory.Exists(organizeStyle))
{
Directory.CreateDirectory(organizeStyle);
}
folderMove = organizeStyle + "\\";
if (!File.Exists(folderMove + chave + ".xml"))
{
File.Copy(arquivoLoad, folderMove + chave + ".xml");
}
label2.Text = "Arquivos sendo processados, aguarde... (" + i + " / " + arquivos + ")";
label2.Refresh();
i++;
}
label2.Text = "Notas organizadas com sucesso!";
label2.Refresh();
}
public static string ReadFileToString(string filePath)
{
using (StreamReader streamReader = new StreamReader(filePath))
{
string text = streamReader.ReadToEnd();
streamReader.Close();
return text;
}
}
public static string RemoveSpecialCharacters(string str)
{
return Regex.Replace(str, #"[^\u0000-\u007F]", string.Empty);
}
private void exitBtn_Click(object sender, EventArgs e)
{
Application.Exit();
}
}
}
How can I determine what 's going on?
The value of a variable pointing to a reference type is not the object at all, its just the memory address where the object lives.
So when you do the following:
while (true)
{
var myVariable = new MyReferenceType();
}
The only memory you are really reusing is the variable itself (think of a 32 or 64 bit pointer). But on every iteration your are allocating somewhere in memory space enough to fit the new object you've just created and that memory is most definitely not the memory reserved to the previous object.
This is essentially why your memory usage is growing. The "old" objects of previous iterations with no live reference will eventually get collected by the GC, but that could be never if the GC decides that it has enough memory available to avoid it.
I have approximately 10 MERGEFIELD in a document that I'm trying to replace the Text with some value. Here's the code.
using (WordprocessingDocument document = WordprocessingDocument.Open(destinationFileName, true))
{
document.ChangeDocumentType(DocumentFormat.OpenXml.WordprocessingDocumentType.Document);
MainDocumentPart docPart = document.MainDocumentPart;
docPart.AddExternalRelationship("http://schemas.openxmlformats.org/officeDocument/2006/relationships/attachedTemplate", new Uri(destinationFileName, UriKind.RelativeOrAbsolute));
docPart.Document.Save();
IEnumerable<FieldChar> fldChars = document.MainDocumentPart.RootElement.Descendants<FieldChar>();
if (fldChars == null) { return; }
string fieldList = string.Empty;
FieldChar fldCharStart = null;
FieldChar fldCharEnd = null;
FieldChar fldCharSep = null;
FieldCode fldCode = null;
string fldContent = String.Empty;
int i = 1;
foreach(var fldChar in fldChars)
{
System.Diagnostics.Debug.WriteLine(i + ": " + fldChar);
i++;
string fldCharPart = fldChar.FieldCharType.ToString();
System.Diagnostics.Debug.WriteLine("Field Char Length: " + fldChar.Count());
System.Diagnostics.Debug.WriteLine("Field Char part: " + fldCharPart);
switch(fldCharPart)
{
case "begin": // start of the field
fldCharStart = fldChar;
System.Diagnostics.Debug.WriteLine("Field Char Start: " + fldCharStart);
// get the field code, which will be an instrText element
// either as sibling or as a child of the parent sibling
fldCode = fldCharStart.Parent.Descendants<FieldCode>().FirstOrDefault();
System.Diagnostics.Debug.WriteLine("Field Code: " + fldCode);
if (fldCode == null)
{
fldCode = fldCharStart.Parent.NextSibling<Run>().Descendants<FieldCode>().FirstOrDefault();
System.Diagnostics.Debug.WriteLine("New Field Code: " + fldCode);
}
if (fldCode != null && fldCode.InnerText.Contains("MERGEFIELD"))
{
fldContent = getFieldValue(query, prescriber, fldCode.InnerText);
fieldList += fldContent + "\n";
System.Diagnostics.Debug.WriteLine("Field content: " + fldContent);
}
break;
case "end": // end of the field
fldCharEnd = fldChar;
System.Diagnostics.Debug.WriteLine("Field char end: " + fldCharEnd);
break;
case "separate": // complex field with text result
fldCharSep = fldChar;
break;
default:
break;
}
if((fldCharStart != null) && (fldCharEnd != null))
{
if(fldCharSep != null)
{
Text elemText = (Text)fldCharSep.Parent.NextSibling().Descendants<Text>().FirstOrDefault();
elemText.Text = fldContent;
System.Diagnostics.Debug.WriteLine("Element text: " + elemText);
// Delete all field chas with their runs
DeleteFieldChar(fldCharStart);
DeleteFieldChar(fldCharEnd);
DeleteFieldChar(fldCharSep);
fldCode.Remove();
}
else
{
Text elemText = new Text(fldContent);
fldCode.Parent.Append(elemText);
fldCode.Remove();
System.Diagnostics.Debug.WriteLine("Element Text !sep: " + elemText);
DeleteFieldChar(fldCharStart);
DeleteFieldChar(fldCharEnd);
DeleteFieldChar(fldCharSep);
}
fldCharStart = null;
fldCharEnd = null;
fldCharSep = null;
fldCode = null;
fldContent = string.Empty;
}
}
System.Diagnostics.Debug.WriteLine("Field list: " + fieldList);
}
It works to some extent. The problem is when there are more than one field in a paragraph. I have about 4 merge fields in one paragraph in this document, and one field in each paragraph after that. Only the first merge field in the paragraph is being updated and the rest fields in the paragraphs is untouched. Then, it moves to the next paragraph and looks for the field. How can I fix this?
Looks like you are over complicating a simple Mailmerge replacement. Instead of looping through paragraphs you could rather get all mailmerge fields within a document and replace them.
private const string FieldDelimeter = " MERGEFIELD ";
foreach (FieldCode field in doc.MainDocumentPart.RootElement.Descendants<FieldCode>())
{
var fieldNameStart = field.Text.LastIndexOf(FieldDelimeter, System.StringComparison.Ordinal);
var fieldName = field.Text.Substring(fieldNameStart + FieldDelimeter.Length).Trim();
foreach (Run run in doc.MainDocumentPart.Document.Descendants<Run>())
{
foreach (Text txtFromRun in run.Descendants<Text>().Where(a => a.Text == "«" + fieldName + "»"))
{
txtFromRun.Text = "Replace what the merge field here";
}
}
}
doc.MainDocumentPart.Document.Save();
doc is of type WordprocessingDocument.
This will replace all merge fields regardless of the amount of fields in a paragraph.