EdSF

Hi All,

I'm relatively new to XML and have been happily generating "simple" XML documents based on a schema (xsd) using the "standard" .net process, which basically goes like this:

XSD -> generate class based on XSD -> use class to deserialize to an XML

it's a beautiful thing!


Now I am coming across things like SSE (simple sharing extensions) and am seeing xml documents with element prefixes. Example:

Code Snippet

<channel>
<sx:sharing
since="Tue, 1 Nov 2004 09:43:33 GMT"
until="Fri, 1 Mar 2005 09:43:33 GMT"
version="0.91" >
<sx:related link="http://x.com/all.xml" type="complete" />
<sx:related link="http://y.net/B.xml" type="aggregated"
title="Family Contacts (Dad's Copy)" />
<sx:related link="http://y.net/C.xml" type="aggregated"
title="Family Contacts (Suzy's Copy)" />
</sx:sharing>

...

</channel>

This may sound elementary to most, but I've been trying and searching in vain for guidance/documentation on how to create an XSD that works (by hand or by using the generation tool of xsd.exe). The goal is to simply generate the above. The concept/semantics are understood as in "the sx prefix is defined in another namespace which you'll find in xmlnsTongue Tiedx="somehwere"...but the "grunt work" of getting the concept working in code is missing...

I'm only using SSE as an example but the real core question is how to generate the element prefix, in the above it would be "sx", using the same process of:

xsd -> class (via xsd tool) -> serialize/deserialize based on class

SSE is not the only use for this. You'll find more RSS extensions (g: for google base; media: for yahoo, itunes, etc. etc.)...so your assistance will be extremely useful Smile

If I create an xml document by hand and use xsd.exe to create a schema for it, it will create 2 xsd files (or more if you have more extensions in use). I've used the xsd tool to create the class by sending both xsds as arguments (not documented but actually works), but the serialized output does not generate the prefix.

So before I drop the beautiful process of xsd -> class -> serialize/deserialize and use the more involved/manual process of using xmlwriters to write elements "manually", I hope there is an answer..

Thanks in advance....




Re: XML and the .NET Framework Element prefixes

Derek Smyth

Hi mate,

I think you can still use the xsd->class->serialize/deserialize process but I believe it might be necessary to change the generated class a little bit by decorating the fields of the class with the xml serialisation attributes. Have a look at the XmlRootAttribute, XmlElementAttribute and similar attributes that are in the System.Xml.Serialisation namespace. You can control the xml serialisation / deserialisation using these attributes.

The element prefixes you see place that element into a namespace. You'll need to decorate your class using the System.Xml.Serialisation attributes so that the fields of the class are placed in the correct namespace.

Take for example

<sx: sharing> the prefix places the sharing element in a namespace which you will see defined in the xml like this xmls: sx="http://....". Namespaces are usually urls. The prefix itself can be anything it's the url that is important.

In your class you can place an element into a namespace like this...

<XmlElement("sharing", Namespace="http://...")>

Dim sharing as String

So that what I think you need to do. Maybe someone will post something more specific but I hope this a least points you in the right direction. Also look up Attributes that control Xml Serialization on MSDN I am sure there is an article on them.






Re: XML and the .NET Framework Element prefixes

Martin Honnen

What matters with XML is not a prefix but the namespace bound to that prefix. That code snippet is not well-formed, there must be some namespace declaration. With XSD schemas you need one schema per namespace and xsd.exe is able to do that, if you have an XML instance document using several namespaces then it will infer several schema documents where one imports the other (look for xs:import elements). When generating classes with the /classes option you simply need to make sure that you provide all schema documents e.g.

Code Snippet

xsd.exe schema1.xsd schema2.xsd /classes






Re: XML and the .NET Framework Element prefixes

EdSF

Derek Smyth wrote:

I think you can still use the xsd->class->serialize/deserialize process but I believe it might be necessary to change the generated class a little bit by decorating the fields of the class with the xml serialisation attributes. Have a look at the XmlRootAttribute, XmlElementAttribute and similar attributes that are in the System.Xml.Serialisation namespace. You can control the xml serialisation / deserialisation using these attributes.

So that what I think you need to do. Maybe someone will post something more specific but I hope this a least points you in the right direction. Also look up Attributes that control Xml Serialization on MSDN I am sure there is an article on them.

Derek,

Yup, that was the "other" avenue I was planning to head into. Just tweak the class generated....but hope there's still one of those "XML gods" on this forum that basically says, "duh, this is how you do it" Smile

Then again, that XML god may just basically say the same thing you did Smile Thank you!






Re: XML and the .NET Framework Element prefixes

EdSF

Martin Honnen wrote:

What matters with XML is not a prefix but the namespace bound to that prefix. That code snippet is not well-formed, there must be some namespace declaration. With XSD schemas you need one schema per namespace and xsd.exe is able to do that, if you have an XML instance document using several namespaces then it will infer several schema documents where one imports the other (look for xs:import elements). When generating classes with the /classes option you simply need to make sure that you provide all schema documents e.g.

Code Snippet

xsd.exe schema1.xsd schema2.xsd /classes

Hi Martin,

Thank you.

Yes, I've gone that far already - that's exactly what I did and without tweaking the generated class as suggested above, the XML output, though sematically correct does not match the format. The sample above is just a snippet of the xml, to keep things simple so to speak. The XML document is well formed (trust me) and contains all the external namespaces and import declarations. That's the only way you can run XSD.exe anyway - otherwise it will not even create the class (it must find the declarations).

The output of the resulting class will look something like:

Code Snippet
<sx xmlns="somewhere">some value</sx>

So "correct" in a way, but no go if the format must be.

Code Snippet
<sx:something>some value</sx>

BTW, SSE is a Microsoft Extension to RSS....so if you're going to build something along the lines of SSE, the resulting XML must be in that form: http://msdn2.microsoft.com/en-us/xml/bb190613.aspx






Re: XML and the .NET Framework Element prefixes

Priya Lakshminarayanan

To get the prefixes generated, you should create an XmlSerializerNamespaces object and add all the prefix/namespace pairs for each namespace used in the document. You should then pass in this object to the serialize method.

The above is explained in more detail here: http://msdn2.microsoft.com/en-us/library/system.xml.serialization.xmlserializernamespaces.aspx

Thanks,

Priya





Re: XML and the .NET Framework Element prefixes

EdSF

Priya Lakshminarayanan - MSFT wrote:

The above is explained in more detail here: http://msdn2.microsoft.com/en-us/library/system.xml.serialization.xmlserializernamespaces.aspx

Hi Priya,

This is great! It does mean modifying the xsd.exe generated class....or simply starting from scratch (forget the xsd generated class)....the latter seems much simpler after going through the above MSDN resource.

THANK YOU!






Re: XML and the .NET Framework Element prefixes

EdSF

UPDATE:

Well, as most of you will notice, the time it took me to reach nirvana was ridiculously short...that includes 10 or so minutes going out for some much needed caffeine!

Same for modifying the XSD generated class, yes, it's riduculously simple - no need to start from scratch whatsoever. Happy coding!

Thanks again to everyone who provided input!