打开XML字内容控件

时间:2015-04-09 07:52:22

标签: ms-word openxml

以下是我的代码尝试使用标记“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"; 
                }

由于查询行,我收到错误“对象引用没有设置为对象的实例”,但我不知道为什么......

当我使用一个内容控件创建一个简单的模板但使用更大的单词模板

时,这种方法效果很好

有什么想法吗?

修改 我尝试不使用.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";
                }
            }

3 个答案:

答案 0 :(得分:0)

并非所有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";
    });

根据评论,我们在answer here中使用Single提供了有关您最初遇到的问题的更多信息。

答案 1 :(得分:0)

试试这个:

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

答案 2 :(得分:0)

接受的解决方案也不对我的查询返回任何结果。所以我想出了这个解决方案;

var doc = document.MainDocumentPart.Document;
List<Tag> sdtSubTable = doc.Body.Descendants<Tag>().Where(r =>
{
return r != null && r.Val.Value.Contains("Company");
}).ToList();