Click here to Skip to main content
15,886,799 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am running some test and using OpenXML now I want to get the data into an Array and save to their respective content controls. I tried and I am getting this execption

Sequence contains no Elements at System.Linq.Enumerable.Single[Tsource](IEnumerable'1 source)


I have this Source code

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\Emeka.Iwuagwu\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());
            }
        }
    }
}


What Do i appear to be missing something?

What I have tried:

I have tried using
SdtElement text_block = mainPart.Document.Body.Descendants<SdtElement>().Where(r => r.SdtProperties.GetFirstChild<Tag>().Val == text).Single();
But I still appear to be missing something what Do I appear to be missing?
Posted
Updated 21-Jan-20 1:59am

Single() implies that an element is being returned from the XML selection. What happens if there is no matching element? If there's a potential that you might not have a value returned, you should use SingleOrDefault() instead.
 
Share this answer
 
Comments
Kayman Luther 21-Jan-20 7:58am    
Shows Object reference not set to an instance of an Object, after changing to SingleOrDefault()
Pete O'Hanlon 21-Jan-20 8:06am    
If you are talking about the processing that happens after SingleOrDefault, it will. You need to check to see whether text_block is null before you attempt to do anything with it.
Kayman Luther 21-Jan-20 8:24am    
I am getting this Text to = text_block.Descendants<text>().Single(); as Null
Why is this so?
Pete O'Hanlon 21-Jan-20 8:34am    
When you get null back here, it's indicating that you have no matching elements being returned.
Kayman Luther 21-Jan-20 8:35am    
But i put it as an Array and the textbox name matches the content controls put on the Word document. It is supposed to get whatever was written inside the textbox to the content control

I am just lost here.
Enumerable.Single method will throw an exception whenever the collection does not hold a single element (i.e., collection is empty or collection contains more than one element). You should probably use Enumerable.SingleOrDefault method which will return null instead of throwing an exception.

Now, as to know why the collection does not contain only one element, I can't say. Best thing to do would probably be to put a breakpoint on the line SdtElement text_block = ... and start a debug session (F5 in Visual Studio). Then you will be able to browse the contents of the Descendants collection and investigate why you are not getting what you expect.

We can provide links on how to conduct a debug session, eventually. Do you need help on performing a debug session?
 
Share this answer
 
Comments
Kayman Luther 21-Jan-20 8:04am    
Shows Object reference not set to an instance of an Object, after changing to SingleOrDefault()
phil.o 21-Jan-20 8:06am    
Same remark: it means the collection does not hold a single element. Time for you to start debugging :)
Kayman Luther 21-Jan-20 8:25am    
I am getting this Text to = text_block.Descendants<text>().Single(); as Null
Why is this so?
phil.o 21-Jan-20 8:34am    
I cannot tell you why since I do not have the data you are working with. This is why you should start debugging.
Kayman Luther 21-Jan-20 8:44am    
I can send the code and the Docx file so you can have a review yourself pls.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900