This project has moved. For the latest updates, please go here.

ReplaceText For Multiple Headers/Sections

Jun 11, 2014 at 6:23 PM
I'm working with a company built template and am very limited on what can be modified as far as layout/structure goes. There are multiple "Next Page" and "Continuous" section breaks throughout the document.

I'm running into an issue where ReplaceText will only modify variables in the last section header. I'm using the most current release of DocX.

I've tried the following:
//only replaces header variables in last section
document.ReplaceText("@sbcPlanHeader", "...data...");

//only replaces header variables in last section
document.Headers.first.ReplaceText("@sbcPlanHeader", "...data...");
document.Headers.even.ReplaceText("@sbcPlanHeader", "...data...");
document.Headers.odd.ReplaceText("@sbcPlanHeader", "...data...");

//sections is null - error thrown
document.Headers.even.Sections[0].ReplaceText("@sbcPlanHeader", "...data...");
document.Headers.odd.Sections[0].ReplaceText("@sbcPlanHeader", "...data...");

//only replaces header variables in last section
//also tried looping through paragraphs, same result
document.Headers.first.Paragraphs[0].ReplaceText("@sbcPlanHeader", "...data...");
document.Headers.even.Paragraphs[0].ReplaceText("@sbcPlanHeader", "...data...");
document.Headers.odd.Paragraphs[0].ReplaceText("@sbcPlanHeader", "...data...");

//sections is null - error thrown
document.Sections[0].ReplaceText("@sbcPlanHeader", plan.PlanDescription);
Also, not all headers are linked back to the first page header as they can be different. I tested linking all headers to see what would happen and they were updated correctly.

I'm not sure what else to try. Any help or point in the right direction would be greatly appreciated. Thanks.
Developer
Jun 11, 2014 at 6:26 PM
" I'm using the most current release of DocX. " as in the one compiled straight from source codes (by yourself)? If not, use that one.
Jun 11, 2014 at 6:34 PM
Yep, that was the first thing I tried to fix the issue. Downloaded and compiled this morning. I probably should have worded that a little better. :)
Jun 16, 2014 at 1:28 PM
I just tested the HeadersAndFooters method in the Examples project in the source code and it seems to function perfectly with the section page break. That narrows down the issue to my template at least. Hopefully, there's something I can do with it to allow the header variables to update.
Jul 10, 2014 at 9:46 AM
Edited Jul 10, 2014 at 9:53 AM
Hello MadBoy and danielhyder,
I'm doing some work in the same area... I don't know if it's a bug or I am doing something wrong. I've just downloaded and using the latest version of source code available.

I'm using this file as test case:
https://dl.dropboxusercontent.com/u/4358337/test.docx (Simple Word file with 3 sections, and 3 different headers, unchained)

This is the code snippet, just enumerating headers, and paragraphs inside them:
using (DocX document = DocX.Load(@"c:\\temp\\test.docx"))
{
if (document.Headers.even != null)
{
Console.WriteLine("Headers even: {0}", document.Headers.even.Paragraphs.Count);
for (int i = 0; i < document.Headers.even.Paragraphs.Count; i++)
Console.WriteLine("Paragraph : {0} Content: {1}", document.Headers.even.Paragraphs[i].Text);
}
else
Console.WriteLine("No Even Headers");

if (document.Headers.odd != null)
{
Console.WriteLine("Headers odd: {0}", document.Headers.odd.Paragraphs.Count);
for (int i = 0; i < document.Headers.odd.Paragraphs.Count; i++)
Console.WriteLine("Paragraph : {0} Content: {1}", i, document.Headers.odd.Paragraphs[i].Text);
}
else
Console.WriteLine("No Odd Headers");

if (document.Headers.first != null)
{
Console.WriteLine("Headers first: {0}", document.Headers.first.Paragraphs.Count);
for (int i = 0; i < document.Headers.first.Paragraphs.Count; i++)
Console.WriteLine("Paragraph : {0} Content: {1}", i, document.Headers.first.Paragraphs[i].Text);
}
else
Console.WriteLine("No First Headers");

}
The output is:

No Even Headers
Headers odd: 1
Paragraph : 0 Content: Header Section 3
No First Headers


But the file contains 3 sections, each section with one Header and each Header with 1 Paragraph inside (Text: Header Section 1, Header Section 2 and Header Section 3)

It seems that only the last one has been detected. If i try to remove the last section, and run the same code the output will be:

No Even Headers
Headers odd: 1
Paragraph : 0 Content: Header Section 2
No First Headers


So still the last Header/Section has been detected

If I quick watch document.Sections i get:
'document.Sections' threw an exception of type 'System.NullReferenceException'

Any idea ?
Jul 10, 2014 at 12:37 PM
I'm pretty much experiencing the same issue with my templates. Only the last header is being detected, so only variables in that header are being replaced. When I tested the example projects it seemed to worked ok so I thought it was something with my template, but maybe that's not the case. I'll take another look at the example project.

Unfortunately, I haven't come up with a fix or work-around so I'm still looking for another solution. I'm trying to avoid interop with Office dlls for my project if at all possible.
Jul 10, 2014 at 1:23 PM
Edited Jul 10, 2014 at 1:25 PM
After further investigation in the source code... i pointed my attention here (File DocX.cs line 590):
string Id =
(
from e in mainDoc.Descendants(XName.Get("body", DocX.w.NamespaceName)).Descendants()
where (e.Name.LocalName == reference) && (e.Attribute(w + "type").Value == type)
 select e.Attribute(r + "id").Value
 ).LastOrDefault();
As you can see, LastOrDefault() gets only the last Header definition. Just try to change LastOrDefault() to ToList() (and string Id with var id) and debug, you'll find that now all the headers are retrieved. But actual source code for some reason gets only the last one....

I tried to modify source code... but the method GetHeaderOrFooterByType() returns a Header (only one, the last in fact) and not a collection so much more work is needed to do that correctly

Then... i thought that Headers and Footers of each section were handled at section level for example:

document.Sections[i].Headers
document.Sections[i].Footers

but that's not the case.... Section/s don't expose Headers or Footers so they are handled at document level (in fact document.Headers and document.Footers)

I think that a more detailed explanation about this from the developers/maintainers of this project could be useful for us :)

.
Unfortunately, I haven't come up with a fix or work-around so I'm still looking for
another solution. I'm trying to avoid interop with Office dlls for my project if at all possible.
Me too ! :)