Finding and replacing placeholders is divided into several <w: t> -Elements

I am trying to create reports from .docx-Templates using the Open XML SDK 2.5. In the templates, I defined some placeholders that are replaced with real values. Placeholders can be defined in various schemes, such as

<#Name#>
or
<!#Name#!>
or
#Name#
or
{{Name}}

The placeholder layout can also be in a different format if the placeholders can be clearly identified within the text.

The problem I am facing right now is that the placeholder is often split into multiple <w:t>-Elements ( DocumentFormat.OpenXml.Wordprocessing.Text) in <w:p>-Element ( DocumentFormat.OpenXml.Wordprocessing.Paragraph). Example

<w:p w:rsidR="003137E0" w:rsidRDefault="008C62F1" w:rsidP="00D43D55">
  <w:r>
    <w:t xml:space="preserve">#FirstName# </w:t>
  </w:r>
  <w:r w:rsidR="00C93A70">
    <w:t>#LastName</w:t>
  </w:r>
  <w:r w:rsidR="005F49B7">
    <w:t>#</w:t>
  </w:r>
</w:p>

placeholder #FirstName# , <w:t> -Element, placeholder #LastName# <w:t> -Elements, Regex ,

Regex placeholderRegex = new Regex(@"#[\w]*#");

document.MainDocumentPart.Document.Body.Descendants<Text>().Where(t=> placeholderRegex.IsMatch(t.Text))

, , , . , <w:t> -Elements.

, {{[\w]*}} .

(Docx)

{{Ort}}
And this {{placeholder}} is within the text 

Xml (OpenXML)

<w:document xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 wp14">
  <w:body>
    <w:p w:rsidR="007B60F2" w:rsidRDefault="00BB7370" w:rsidP="00D43D55">
      <w:pPr>
        <w:rPr>
          <w:lang w:val="en-US" />
        </w:rPr>
      </w:pPr>
      <w:r w:rsidRPr="00114EA7">
        <w:rPr>
          <w:lang w:val="en-US" />
        </w:rPr>
        <w:t>{{</w:t>
      </w:r>
      <w:r w:rsidR="00C93A70" w:rsidRPr="00114EA7">
        <w:rPr>
          <w:lang w:val="en-US" />
        </w:rPr>
        <w:t>Ort</w:t>
      </w:r>
      <w:r w:rsidR="00114EA7" w:rsidRPr="00114EA7">
        <w:rPr>
          <w:lang w:val="en-US" />
        </w:rPr>
        <w:t>}}</w:t>
      </w:r>
    </w:p>
    <w:p w:rsidR="00EC3BED" w:rsidRPr="00114EA7" w:rsidRDefault="00C310E0" w:rsidP="00D43D55">
      <w:pPr>
        <w:rPr>
          <w:lang w:val="en-US" />
        </w:rPr>
      </w:pPr>
      <w:r w:rsidRPr="00114EA7">
        <w:rPr>
          <w:lang w:val="en-US" />
        </w:rPr>
        <w:t xml:space="preserve">This is a text with a </w:t>
      </w:r>
      <w:r w:rsidR="00A07A5D">
        <w:rPr>
          <w:lang w:val="en-US" />
        </w:rPr>
        <w:t>{{</w:t>
      </w:r>
      <w:r w:rsidRPr="00114EA7">
        <w:rPr>
          <w:lang w:val="en-US" />
        </w:rPr>
        <w:t>placeholder</w:t>
      </w:r>
      <w:r w:rsidR="00A07A5D">
        <w:rPr>
          <w:lang w:val="en-US" />
        </w:rPr>
        <w:t>}</w:t>
      </w:r>
      <w:r w:rsidR="00114EA7" w:rsidRPr="00114EA7">
        <w:rPr>
          <w:lang w:val="en-US" />
        </w:rPr>
        <w:t>}</w:t>
      </w:r>
      <w:bookmarkStart w:id="0" w:name="_GoBack" />
      <w:bookmarkEnd w:id="0" />
      <w:r w:rsidR="00A07A5D">
        <w:rPr>
          <w:lang w:val="en-US" />
        </w:rPr>
        <w:t>.</w:t>
      </w:r>
    </w:p>
    <w:sectPr w:rsidR="00EC3BED" w:rsidRPr="00114EA7" w:rsidSect="00237721">
      <w:pgSz w:w="11906" w:h="16838" />
      <w:pgMar w:top="1417" w:right="1417" w:bottom="1134" w:left="1417" w:header="708" w:footer="708" w:gutter="0" />
      <w:cols w:space="708" />
      <w:docGrid w:linePitch="360" />
    </w:sectPr>
  </w:body>
</w:document>

, , Open XML SDK? - SDK, ? - ?

+4
3

, MS Word Run/Text ( - ). , Find/Replace, Open XML SDK. Paragraph/Run/Text. :

  • , Run/Text .
  • (, < # Name # > ) Run/Text , , . , .
+1

- ( , , ):

placeHolders = List();

//load xml string
var doc = XDocument.Parse(xml);
//or to load from file use XDocument.Load("path_to_xml_file.xml");

//get all <w:p> element
var wpElements = doc.Root.Elements("w:p");

foreach (var wp in wpElements)
{
    var wrElements = wp.Descendants("w:r");
    foreach (var wr in wrElements)
    {
        var wt = (string)wr.Element("w:t");
        if (wt.IsMatch(@"\w")) { //add the string to placeHolders if word is found 
            placeHolders.Add(wt);
        }
        else
        {
            //if not found a word, add it to the last placeHolder, 
            placeHolder[placeHolder.Count - 1] = placeHolder[placeHolder.Count - 1] + wt;
        }
    }
}
+1

Source: https://habr.com/ru/post/1536054/


All Articles