问题
Here is my code trying to get the content controls with the tag "company"
using (WordprocessingDocument template = WordprocessingDocument.Open("d:/dev/ProposalTemplate1.dotx", true))
{
MainDocumentPart mainPart = template.MainDocumentPart;
SdtBlock block = mainPart.Document.Body.Descendants<SdtBlock>().Where(r => r.SdtProperties.GetFirstChild<Tag>().Val == "TEST").Single();
Text t = block.Descendants<Text>().Single();
t.Text = "COMPANY_NAME";
}
I got the error "Object reference not set to an instance of an object" because of the query line but I don't know why...
This works well when I create a simple template with just one content controls but not when using a bigger word template
Any idea ?
EDIT
I try doing it without .Single()
but still not working
MainDocumentPart mainPart = template.MainDocumentPart;
var blocks = mainPart.Document.Body.Descendants<SdtBlock>().Where(r => r.SdtProperties.GetFirstChild<Tag>().Val == "Company");
foreach (SdtBlock block in blocks)
{
Text t = block.Descendants<Text>().Single();
t.Text = "COMPANY1";
}
EDIT 2
I change the Text.Single()
The problem is still there "Object reference not set to an instance of an object" on the SdtBlock block = ...
line
MainDocumentPart mainPart = template.MainDocumentPart;
var blocks = mainPart.Document.Body.Descendants<SdtBlock>().Where(r => r.SdtProperties.GetFirstChild<Tag>().Val == "Company");
foreach (SdtBlock block in blocks)
{
var t = block.Descendants<Text>();
foreach (Text text in t)
{
text.Text = "COMPANY1";
}
}
回答1:
Not all SdtBlock
elements have child Tag
elements. You are assuming one exists and attempting to access the Val
property but are getting a null reference exception in doing so.
You can fix it by checking for null within the Where
predicate:
var blocks = mainPart.Document.Body.Descendants<SdtBlock>().Where(r =>
{
var tag = r.SdtProperties.GetFirstChild<Tag>();
return tag != null && tag.Val == "Company";
});
As per the comments there is more information about the issues you originally had with using Single
in my answer here.
回答2:
Try this:
foreach( SdtBlock sdt in sdtList )
{
if( sdt.SdtProperties != null )
{
Tag tag = sdt.SdtProperties.GetFirstChild<Tag>();
if( tag!= null )
{
if( tag.Val.Value == "Company" )
{
if( sdt.InnerText != string.Empty )
{
//Do something
}
}
}
}
}
回答3:
Accepted solution returns no results on my query either. So i come up with this solution;
var doc = document.MainDocumentPart.Document;
List<Tag> sdtSubTable = doc.Body.Descendants<Tag>().Where(r =>
{
return r != null && r.Val.Value.Contains("Company");
}).ToList();
来源:https://stackoverflow.com/questions/29532841/open-xml-word-content-controls