Элементы управления содержимым Open XML word

Вот мой код, пытающийся получить управление контентом с тегом "компания"

                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"; 
                }

Я получил ошибку "Ссылка на объект не установлена ​​на экземпляр объекта" из-за строки запроса, но я не знаю почему...

Это хорошо работает, когда я создаю простой шаблон только с одним элементом управления контентом, но не при использовании большого шаблона слов

Любая идея?

РЕДАКТИРОВАТЬ Я пытаюсь сделать это без .Single() но все еще не работает

            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";
            }

РЕДАКТИРОВАТЬ 2 Я изменяю Text.Single() Проблема все еще там "Ссылка на объект не установлена ​​на экземпляр объекта" на SdtBlock block = ... линия

            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";
                }
            }

2 ответа

Решение

Не все SdtBlock элементы имеют ребенка Tag элементы. Вы предполагаете, что он существует, и пытаетесь получить доступ к Val свойство, но получают исключение нулевой ссылки при этом.

Вы можете исправить это, проверив нулевое значение в Where сказуемое:

var blocks = mainPart.Document.Body.Descendants<SdtBlock>().Where(r => 
    {
        var tag = r.SdtProperties.GetFirstChild<Tag>();
        return tag != null && tag.Val == "Company";
    });

Согласно комментариям, есть больше информации о проблемах, которые у вас изначально были с использованием Single в моем ответе здесь.

Попробуй это:

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
                                    }
                                }
                            }
                        }
                    }

Принятое решение также не дает результатов по моему запросу. Так что я придумала это решение;

var doc = document.MainDocumentPart.Document;
List<Tag> sdtSubTable = doc.Body.Descendants<Tag>().Where(r =>
{
return r != null && r.Val.Value.Contains("Company");
}).ToList();
Другие вопросы по тегам