3

I have the following code below. I am getting an error "the character ':' hexadecimal value 0x3A cannot be included in a name" Can anyone tell me how to fix this? Thanks Below is the entire code

 public static XDocument GenerateXMLSpreadSheet(DataTable tbl)
    {
         new XDocument(   
            new XDeclaration("1.0", "utf-8", "yes"),   
            new XProcessing**Instruction("mso-application", "Excel.Sheet"),   
            new XElement("Workbook",   
                new XAttribute("xmlns", "urn:schemas-microsoft-com:office:spreadsheet"),   
                new XAttribute("xmlns:ss", "urn:schemas-microsoft- 
                      com:office:spreadsheet"),   
                    new XElement("Worksheet", new XAttribute("ss:Name",  
                        tbl.TableName),
                        new XElement("Table", GetRows(tbl)   
                        )
                    )
                )
            );
        return xmlssDoc;    
)
 public static Object[] GetRows(DataTable tbl)
    {
        // generate XElement rows for each row in the database.
        // generate from the bottom-up.
        // start with the cells.
        XElement[] rows = new XElement[tbl.Rows.Count];

        int r = 0;
        foreach (DataRow row in tbl.Rows)
        {
            // create the array of cells to add to the row:
            XElement[] cells = new XElement[tbl.Columns.Count];
            int c = 0;
            foreach (DataColumn col in tbl.Columns)
            {
                cells[c++] =
                    new XElement("Cell",
                        new XElement("Data", new XAttribute("ss:Type", "String"),
                            new XText(row[col].ToString())));
            }
            rows[r++] = new XElement("Row", cells);
        }
        // return the array of rows.
        return rows;
    }
5
  • 2
    "I am getting an error" - where? Is this at compile-time, or as an exception? Always think about what information is going to be important to someone trying to help you. I strongly suspect it's this: new XAttribute("xmlns:ss", "urn:schemas-microsoft-com:office:spreadsheet") but that should be part of the question. Commented Feb 2, 2018 at 14:31
  • 1
    It would also help if you'd provide a minimal reproducible example - currently you have line breaks in your sample code, and it refers to tbl Commented Feb 2, 2018 at 14:32
  • The error occurs at run time. Not sure of the exact location, It highlights the entire code above. The Getrows function never gets called as it errors out before that. That code passes a data table tbl and creates Xelements for each row Commented Feb 2, 2018 at 14:39
  • 2
    "Not sure of the exact location" - that suggests you should try to reduce it to a smaller example, maybe debugging into the code and step through one call at a time. It's important to learn the art of diagnostics like this. Commented Feb 2, 2018 at 14:41
  • try to split your function in three. one for each "for" loop. Then you will have better control of your code. Commented Feb 24, 2018 at 3:26

2 Answers 2

5

Basically, that's not how you handle namespaces in LINQ to XML. You never specify a string with a colon in - instead, you build up an XName from an XNamespace and a string.

The good news is that LINQ to XML handling of namespaces is simple. Here's a complete example:

using System;
using System.Xml.Linq;

public class Test
{
    static void Main(string[] args)
    {
        XNamespace ns = "urn:schemas-microsoft-com:office:spreadsheet";
        var doc = new XDocument(   
            new XDeclaration("1.0", "utf-8", "yes"),   
            new XProcessingInstruction("mso-application", "Excel.Sheet"),   
            new XElement(ns + "Workbook",
                new XAttribute("xmlns", ns),
                new XAttribute(XNamespace.Xmlns + "ss", ns),
                new XElement(ns + "Worksheet", 
                   new XAttribute(ns + "Name", "my-table-name"),
                   new XElement(ns + "Table")
                )
            )
        );
        Console.WriteLine(doc);
    }
}

Output (reformatted for clarity):

<?mso-application Excel.Sheet?>
<ss:Workbook
    xmlns="urn:schemas-microsoft-com:office:spreadsheet" 
    xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">
  <ss:Worksheet ss:Name="my-table-name">
    <ss:Table />
  </ss:Worksheet>
</ss:Workbook>

Note how you need to specify the namespace for all the elements and attributes.

Because you've specified an explicit prefix for the namespace, LINQ to XML uses it everywhere. If you remove this part:

new XAttribute(XNamespace.Xmlns + "ss", ns)

... then the namespace for elements will be defaulted, and LINQ to XML will generate a prefix for the attributes that need it explicitly specified (as attributes don't default their namespaces).

Then the output is (for example):

<?mso-application Excel.Sheet?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet">
  <Worksheet p2:Name="my-table-name" xmlns:p2="urn:schemas-microsoft-com:office:spreadsheet">
    <Table />
  </Worksheet>
</Workbook>
Sign up to request clarification or add additional context in comments.

Comments

1

The problem is how you defined namespaces.
To work with namespaces you may get one by calling XNamespace.Get("the namespace") and using this everywhere you want.

And for xmlns you may use static property XNamespace.Xmlns.

So the final code will look like:

new XDocument(
    new XDeclaration("1.0", "utf-8", "yes"),
    new XProcessingInstruction("mso-application", "Excel.Sheet"),
    new XElement("Workbook",
        new XAttribute("xmlns", ns),
        new XAttribute(XNamespace.Xmlns + "ss", ns),   

            new XElement("Worksheet", new XAttribute(ns + "Name",
                tbl.TableName),
                new XElement("Table", GetRows(tbl)
                )
            )
        )
    );

2 Comments

There are more problems than just that in the end though.
@JonSkeet, hey is that you or the bot? :))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.