我正在运行一些测试并使用 OpenXML,现在我想将数据放入数组中并保存到各自的内容控件中。我试过了,我得到了这个例外
Sequence contains no Elements at System.Linq.Enumerable.Single[Tsource](IEnumerable'1 source)
有了这个源代码:
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace PopulateContentsOpenXml
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string myfile = @"C:\Users\*****\Desktop\DTestDoc.docx";
string[] writeDocData = new string[] {FirstName.Text,FileNumber.Text,IDNumber.Text,LastName.Text };
WriteDataToContentControl(myfile, writeDocData);
}
private void WriteDataToContentControl(string filename,string[]data)
{
try
{
using (WordprocessingDocument doc = WordprocessingDocument.Open(filename, true))
{
MainDocumentPart mainPart = doc.MainDocumentPart;
foreach (string text in data)
{
SdtElement text_block = mainPart.Document.Body.Descendants<SdtElement>().Where(r => r.SdtProperties.GetFirstChild<Tag>().Val == text).Single();
Text to = text_block.Descendants<Text>().Single();
to.Text = text;
mainPart.Document.Save();
MessageBox.Show("Ok i am fine now!");
}
}
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex.ToString());
}
}
}
}
我在第 39 行收到异常,也就是这一行
SdtElement text_block = mainPart.Document.Body.Descendants<SdtElement>().Where(r => r.SdtProperties.GetFirstChild<Tag>().Val == text).Single();
编辑 这样做
SdtElement text_block = mainPart.Document.Body.Descendants<SdtElement>().Where(r => r.SdtProperties.GetFirstChild<Tag>().Val == text).SingleOrDefault();
Text to = text_block.Descendants<Text>().Single();
我没有将对象设置为对象的实例。现在检查后,它说 text_block 为 null
为什么会这样?
有许多 Linq 扩展方法会在序列(例如,
IEnumerable<T>
)为空或不满足您通过调用该方法所做的断言的情况下引发异常。
如果您的序列不包含 恰好一个
元素,
Single<TSource>()
将引发异常。因此,如果序列为空或包含多个元素,它会引发异常。这就是发生在你身上的事。给定标签值不存在 SdtElement
。
如果序列为空,First<TSource>()
和Last<TSource>()
也会抛出异常。他们期望序列中至少有一个元素。
如果您不能保证您的序列非空,这意味着它将准确包含或至少包含一个 SdtElement
,您应该使用
SingleOrDefault<TSource>()
或潜在的
FirstOrDefault<TSource>()
。如果序列为空,
SingleOrDefault<TSource>()
不会抛出异常,但如果序列包含多个元素,则会抛出异常。因此,它期望最多一个元素。
FirstOrDefault<TSource>()
在任何情况下都不会抛出。如果
null
实例序列为空,它将返回
SdtElement
。如果不为空,它将返回第一个
SdtElement
,忽略其他。因此,它需要零个或更多元素。