I'm trying to find all SdtElement in a Word document. I have used the below code:
using (var wordDoc = WordprocessingDocument.Open(FilePath, true))
{
var docSdts = wordDoc.MainDocumentPart.Document.Descendants<SdtElement>();
// MainDocumentPart.Document.Body.Descendants<SdtElement>(); also used but same result
MainDocumentPart mainPart = wordDoc.MainDocumentPart;
List<SdtBlock> sdtList = mainPart.Document.Body.Descendants<SdtBlock>().ToList();
// process all sdt
}
The issue is the above code does not return all SdtElements from the file. In one document there are 19 SdtElements but it returns only 7.
As per document, the Descendants method should return elements from all levels:
Elements finds only those elements that are direct descendents, i.e. immediate children. vs Descendants finds children at any level, i.e. children, grand-children, etc...
One thing observed was only sdt under body, para, and table cells are returned, but when the sdt is under para inside a table cell, it is not returned.
I tried the code from http://www.ericwhite.com/blog/iterating-through-all-content-controls-in-an-open-xml-wordprocessingml-document/ and other similar articles.
How do I get all sdt elements from the entire document irrespective of the nesting levels?
SdtElement
is base class for other sdt elements:
You are trying to get only SdtBlock
elements:
List<SdtBlock> sdtList = mainPart.Document.Body.Descendants<SdtBlock>().ToList();
If you want to get all SdtElements
you should change it to:
List<SdtElement> sdtList = mainPart.Document.Body.Descendants<SdtElement>().ToList();
Note that the SdtElements
may also be in other parts of the WordprocessingDocument
like:
In that case you should iterate over all those parts, for example:
List<SdtElement> sdtList = mainPart.Document.Body.Descendants<SdtElement>().ToList();
foreach(var part in mainPart.Document.HeaderParts)
{
sdtList.AddRange(part.Header.Descedants<SdtElement>());
}
foreach(var part in mainPart.Document.FooterParts)
{
sdtList.AddRange(part.Footer.Descedants<SdtElement>());
}