By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,715 Members | 1,815 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,715 IT Pros & Developers. It's quick & easy.

Serializing Class with Unqualified Root Element and Default Namespace attribute

P: n/a
I'm trying to serialize (using XmlSerializer.Serialize) a class that I generated from an XSD schema using XSD.EXE /c.

The problem I'm running into is that the root element needs to be unqualified, and the default namespace needs to be included on it
as an attribute. The schema I'm using is this:

<xs:schema
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:html="http://www.w3.org/TR/REC-html40"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:c="urn:schemas-microsoft-com:office:component"
attributeFormDefault="unqualified"
targetNamespace="urn:schemas-microsoft-com:office:spreadsheet"
elementFormDefault="unqualified">
<xs:import namespace="urn:schemas-microsoft-com:office:office" />
<xs:import namespace="urn:schemas-microsoft-com:office:excel" />
<xs:import namespace="urn:schemas-microsoft-com:office:component" />
<xs:element name="Workbook">...
<xs:complexType>
<xs:sequence>
<xs:element ref="o:DocumentProperties" />
<xs:element ref="o:OfficeDocumentSettings" />
<xs:element ref="x:ExcelWorkbook" />

But when I use Serialize() I get this:

<?xml version="1.0" encoding="utf-8"?>
<ss:Workbook
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:c="urn:schemas-microsoft-com:office:component"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">...

Which is close, but not close enough.

I tried specifying the default namespace in the call to Serialize(), but it didn't have any effect, on either the qualification on
the Workspace node or the lack of the xmlns attribute on the node.

- Mark

Specifically, I need this:

<Workbook
xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:c="urn:schemas-microsoft-com:office:component"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">

Mar 12 '07 #1
Share this Question
Share on Google+
9 Replies


P: n/a
Mark Olbert wrote:
But when I use Serialize() I get this:

<?xml version="1.0" encoding="utf-8"?>
<ss:Workbook
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:c="urn:schemas-microsoft-com:office:component"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">...

Which is close, but not close enough.
Specifically, I need this:

<Workbook
xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:c="urn:schemas-microsoft-com:office:component"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">
Semantically there is no difference between the two snippets, it does
not matter in terms of XML and namespaces whether a namespace is used as
the default namespace or with a prefix.

Can you show us the relevant C# or VB.NET class definition of the
objects you serialize? There are attributes that set the namespace and
the Serialize method has a third argument that maps prefixes to
namespace URI so this class

[XmlRoot(Namespace =
"urn:schemas-microsoft-com:office:spreadsheet", ElementName = "Workbook")]
public class Foo
{
public Foo() { }
}

with this code

Foo foo = new Foo();
XmlSerializer serializer = new XmlSerializer(typeof(Foo));
serializer.Serialize(Console.Out, foo);

serializes as

<Workbook xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="urn:schemas-microsoft-com:office:spreadsheet" />

while using this code

XmlSerializerNamespaces namespaces = new
XmlSerializerNamespaces();
namespaces.Add("ss",
"urn:schemas-microsoft-com:office:spreadsheet");
serializer.Serialize(Console.Out, foo, namespaces);

it serializes as
<ss:Workbook xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" />
--

Martin Honnen --- MVP XML
http://JavaScript.FAQTs.com/
Mar 12 '07 #2

P: n/a
Hi Mark

According to your description, what you need is the root element should be
unqualified. If I have misunderstood anything here, please feel free to let
me know.

The XSD schema which you posted in newsgroup is fine.

It seems like you Serialize the WorkBook class conjunction with
XmlSerializerNamespaces.
Public void Serialize (XmlWriter xmlWriter, Object o,
XmlSerializerNamespaces namespaces)
Would you please past some code snippet about how did you serialize the
WorkBook Class?

As far as I know, there are two ways you can use to serialize the root
element as unqualified.
Senaro 1:
Stream writer = new FileStream("Workbook.xml", FileMode.Create);
XmlSerializerNamespaces xsnx = new XmlSerializerNamespaces();
xsnx.Add("", " urn:schemas-microsoft-com:office:spreadsheet");
xsns.Add(...); // other namespaces
XmlSerializer serializer = new XmlSerializer(typeof(Workbook));
serializer.Serialize(writer, objWorkbook, xsnx);

Senaro 2:
Stream writer = new FileStream("Workbook.xml", FileMode.Create);
XmlSerializer serializer = new XmlSerializer(typeof(Workbook));
serializer.Serialize(writer, objWorkbook);
Hope this helps.
Sincerely,
Wen Yuan

Mar 12 '07 #3

P: n/a
Martin,

>Semantically there is no difference between the two snippets, it does not matter in terms of XML and namespaces whether a namespace is used as
the default namespace or with a prefix.
Unfortunately, it appears to matter a great deal to Microsoft Excel. In testing on both Excel XP and Excel 2007, not having that
xmlns="..." attribute prevents the file from being parsed. Personally, and not knowing much about XML, I think having two attributes
that point at the same namespace (i.e., xmlns="..." and xmlns:ss="<same>") strikes me as weird...but apparently not to the folks who
wrote Excel :).
>Can you show us the relevant C# or VB.NET class definition of the objects you serialize? There are attributes that set the namespace and
the Serialize method has a third argument that maps prefixes to namespace URI so this class
[System.CodeDom.Compiler.GeneratedCodeAttribute("xs d", "2.0.50727.42")]
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("c ode")]
[System.Xml.Serialization.XmlTypeAttribute(Anonymou sType=true)]
[System.Xml.Serialization.XmlRootAttribute(Namespac e="urn:schemas-microsoft-com:office:spreadsheet", IsNullable=false)]
public partial class Workbook
{
}

and

XmlSerializer serializer = new XmlSerializer(typeof(Workbook));

XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("x", "urn:schemas-microsoft-com:office:excel");
ns.Add("c", "urn:schemas-microsoft-com:office:component");
ns.Add("html", "http://www.w3.org/TR/REC-html40");
ns.Add("ss", "urn:schemas-microsoft-com:office:spreadsheet");

serializer.Serialize(tw, this, ns); // this is a Workbook object

generates:

<?xml version="1.0" encoding="utf-8"?>
<ss:Workbook xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:html="http://www.w3.org/TR/REC-html40"
xmlns:c="urn:schemas-microsoft-com:office:component" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">
<Worksheet ss:Name="Sheet1">

which doesn't work because the default xmlns tag is missing. Not adding the "ss" namespace to namespaces generates:

<?xml version="1.0" encoding="utf-8"?>
<Workbook xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:html="http://www.w3.org/TR/REC-html40"
xmlns:c="urn:schemas-microsoft-com:office:component" xmlns="urn:schemas-microsoft-com:office:spreadsheet">
<Worksheet d2p1:Name="Sheet1" xmlns:d2p1="urn:schemas-microsoft-com:office:spreadsheet" xmlns="">

which doesn't work because the Worksheet element redefines the default namespace to "". FYI, the Worksheet class definition is as
follows:

[System.CodeDom.Compiler.GeneratedCodeAttribute("xs d", "2.0.50727.42")]
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("c ode")]
[System.Xml.Serialization.XmlTypeAttribute(Anonymou sType=true, Namespace="urn:schemas-microsoft-com:office:spreadsheet")]
public partial class WorkbookWorksheet
{
}

Adding the named tag ElementName="Workbook" to the XmlRootAttribute while not adding the ss namespace to the serializer generates

<?xml version="1.0" encoding="utf-8"?>
<Workbook xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:html="http://www.w3.org/TR/REC-html40"
xmlns:c="urn:schemas-microsoft-com:office:component" xmlns="urn:schemas-microsoft-com:office:spreadsheet">
<Worksheet d2p1:Name="Sheet1" xmlns:d2p1="urn:schemas-microsoft-com:office:spreadsheet" xmlns="">

which suppresses the ss: prefix on the Workbook node, but still has the problem of the Worksheet node redefining xmlns.

Adding the Namespace= parameter to the XmlTypeAttribute on WorkbookWorksheet:

[System.CodeDom.Compiler.GeneratedCodeAttribute("xs d", "2.0.50727.42")]
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("c ode")]
[System.Xml.Serialization.XmlTypeAttribute(Anonymou sType = true, Namespace = "urn:schemas-microsoft-com:office:spreadsheet")]
public partial class WorkbookWorksheet
{
}

generates

<?xml version="1.0" encoding="utf-8"?>
<Workbook xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:html="http://www.w3.org/TR/REC-html40"
xmlns:c="urn:schemas-microsoft-com:office:component" xmlns="urn:schemas-microsoft-com:office:spreadsheet">
<Worksheet d2p1:Name="Sheet1" xmlns:d2p1="urn:schemas-microsoft-com:office:spreadsheet" xmlns="">

again with the redefinition of the default namespace on the Worksheet node.

The schema where Workbook and Worksheet are defined looks like this (some hopefully unrelated details left out for brevity):

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:html="http://www.w3.org/TR/REC-html40"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:c="urn:schemas-microsoft-com:office:component" attributeFormDefault="unqualified"
targetNamespace="urn:schemas-microsoft-com:office:spreadsheet" elementFormDefault="unqualified">
<xs:import namespace="urn:schemas-microsoft-com:office:office" />
<xs:import namespace="urn:schemas-microsoft-com:office:excel" />
<xs:import namespace="urn:schemas-microsoft-com:office:component" />
<xs:element name="Workbook">
<xs:complexType>
<xs:sequence>
<xs:element name="Styles">
</xs:element>
<xs:element maxOccurs="unbounded" name="Worksheet">
<xs:complexType>
<xs:sequence>
</xs:sequence>
<xs:attribute ref="ss:Name" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
....

I appreciate your help, and look forward to other suggestions.

- Mark

Mar 12 '07 #4

P: n/a
Wen Yuan,

Please see my reply to Martin. I tried your suggestions, but they don't solve the problem.

- Mark
Mar 12 '07 #5

P: n/a
Mark Olbert wrote:
The schema where Workbook and Worksheet are defined looks like this (some hopefully unrelated details left out for brevity):

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:html="http://www.w3.org/TR/REC-html40"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:c="urn:schemas-microsoft-com:office:component" attributeFormDefault="unqualified"
targetNamespace="urn:schemas-microsoft-com:office:spreadsheet" elementFormDefault="unqualified">
Why is elementFormDefault set to unqualified? The MS reference schema
for Office 2003 sets that to qualified.

--

Martin Honnen --- MVP XML
http://JavaScript.FAQTs.com/
Mar 12 '07 #6

P: n/a
Martin,

That schema was generated by having VS2005 generate a schema off of an Excel XP XML file. In the Excel XP XML file the element names
are unqualified (I just double-checked that).

I don't know why that would've changed between Excel XP and Excel 2003.

Interestingly, changing the element form to qualified solved the problem. The generated XML file now looks like:

<?xml version="1.0" encoding="utf-8"?>
<ss:Workbook xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:html="http://www.w3.org/TR/REC-html40"
xmlns:c="urn:schemas-microsoft-com:office:component" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">
<ss:Worksheet ss:Name="Sheet1">
<ss:Table>
<ss:Row ss:Index="1">
<ss:Cell ss:Index="1">
<ss:Data ss:Type="String">Ralphie</ss:Data>
</ss:Cell>
</ss:Row>
<ss:Row ss:Index="4">
<ss:Cell ss:Index="4">
<ss:Data ss:Type="String">Joanie</ss:Data>
</ss:Cell>
</ss:Row>
</ss:Table>
</ss:Worksheet>
</ss:Workbook>

which Excel 2007 (I just upgraded, so I no longer have Excel XP to test with) is happy to load as an Excel file.

So the problem's solved (at least for now). Thank you!

I double-checked the file I used to generate the schema to see if it would load in Excel 2007. It does, without a hitch. Here's what
it looks like (edited for brevity):

<?xml version="1.0"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:html="http://www.w3.org/TR/REC-html40">
<Worksheet ss:Name="Sheet1">
<Table ss:ExpandedColumnCount="4" ss:ExpandedRowCount="6" x:FullColumns="1"
x:FullRows="1" ss:DefaultColumnWidth="60" ss:DefaultRowHeight="15">
<Row ss:AutoFitHeight="0">
<Cell><Data ss:Type="Number">1</Data></Cell>
</Row>
<Row ss:AutoFitHeight="0">
<Cell><Data ss:Type="Number">2</Data></Cell>
</Row>
<Row ss:AutoFitHeight="0"/>
<Row ss:AutoFitHeight="0">
<Cell ss:Index="2"><Data ss:Type="String">a</Data></Cell>
</Row>
<Row ss:AutoFitHeight="0"/>
<Row ss:AutoFitHeight="0">
<Cell ss:Index="4"><Data ss:Type="String">c</Data></Cell>
</Row>
</Table>
</Worksheet>
</Workbook>

I still wish I understood >>why<< it was solved, though, and why Excel XP generated an XML file with unqualified element names. It
looks like, if the xmlns attribute is specified on the root node you don't need to qualify the element names, but if it isn't, you
have to. Since I haven't been able to find a way to get the xmlns attribute added to the root node when I generate a file, I have to
qualify the element names.

Then again, if I had a dollar for every XML/XSD/namespace issue I didn't understand, I'd be filthy rich.

- Mark

On Mon, 12 Mar 2007 18:31:26 +0100, Martin Honnen <ma*******@yahoo.dewrote:
>Mark Olbert wrote:
>The schema where Workbook and Worksheet are defined looks like this (some hopefully unrelated details left out for brevity):

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:html="http://www.w3.org/TR/REC-html40"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:c="urn:schemas-microsoft-com:office:component" attributeFormDefault="unqualified"
targetNamespace="urn:schemas-microsoft-com:office:spreadsheet" elementFormDefault="unqualified">

Why is elementFormDefault set to unqualified? The MS reference schema
for Office 2003 sets that to qualified.
Mar 12 '07 #7

P: n/a
Mark Olbert wrote:
I double-checked the file I used to generate the schema to see if it would load in Excel 2007. It does, without a hitch. Here's what
it looks like (edited for brevity):

<?xml version="1.0"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:html="http://www.w3.org/TR/REC-html40">
<Worksheet ss:Name="Sheet1">
You misunderstand what elementFormDefault="unqualified" means. In that
sample both elements, the Workbook element, and the Worksheet element,
are in the namespace urn:schemas-microsoft-com:office:spreadsheet and a
schema modelling that needs
targetNamespace="urn:schemas-microsoft-com:office:spreadsheet"
and
elementFormDefault="qualified"
.. The schema you had with a
targetNamespace="urn:schemas-microsoft-com:office:spreadsheet" but with
elementFormDefault="unqualified" describes a Workbook element in the
targetNamespace where child elements like Worksheet are in no namespace,
hence the xmlns="" you got on that element.

--

Martin Honnen --- MVP XML
http://JavaScript.FAQTs.com/
Mar 13 '07 #8

P: n/a
Hi Mark,

Additionally, XML namespaces is used to provide a simple method for
qualifying element and attribute names used in XML documents.

For example:
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:html="http://www.w3.org/TR/REC-html40">
<Worksheet ss:Name="Sheet1">

"urn:schemas-microsoft-com:office:spreadsheet' is the default namespace for
both <Workbookand <WorkSheetelement.

But if you have many <WorkBookelements with the different meaning in XML
document, then how do you distinguish these <WorkBookelements?
Namespace can help you in this scenario.

< Workbook xmlns="namespace1">
...< Worksheet >
......< Workbook xmlns="namespace2">
.........
......</WorkBook>
...</ Worksheet >
</ Workbook>

You can distinguish the root <Workbookelement by namespace "namespace1"
and node <Workbook\Worksheet\Workbookby namespace "namespace2".

Hope this will help you understand namespace.

You can get more detailed information by the following document.
http://www.w3.org/TR/REC-xml-names/
[Namespaces in XML 1.0 (Second Edition)]

Have a great day,
Sincerley,
Wen Yuan

Mar 15 '07 #9

P: n/a
Hi Martin,

Just want to check whether you have met any further issue?
Please feel free to update here. I'm glad to assist you.

Have a great day,
Sincerely,
Wen Yuan

Mar 19 '07 #10

This discussion thread is closed

Replies have been disabled for this discussion.