views:

123

answers:

4

I'm working with some XML representations of data instances. I'm deserializing the objects using .NET serialization but something in my soul is disturbed by having to write classes to represent the XML... Below is what I'd LOVE to do but I don't know if the syntax or if it is even possible:

Consider the following:

dim xmlObject = SomeXMLFunction() 'where some function returns an object/string representation of xml...

xmlObject.SomePropertyDefinedInTheXML = SomeFunction()

Any suggestions on approachs with this?

+4  A: 

Go and get xsd.exe. It'll create proper XML serialization classes from your schema definition. Automatically!

David Schmitt
1. I don't have a schema :-(2. I have a utility to parse xml myself but it doesn't feel right.3. Cool answer +1
Achilles
You should have one. You should make one. xsd.exe can help you: "If you specify an XML file (.xml extension), Xsd.exe infers a schema from the data in the file and produces an XSD schema."
David Schmitt
I think the spirit of my question is to avoid generating classes. Your answer is very helpful though. I'll use this approach if I can't get "this" approach to work.
Achilles
There is no way to call class methods (xmlObject.SomeProperty...) unless you generate a class. Your only option, if you want to call a class method, is to create a class.
overslacked
That might change with .net4.0's `dynamic`. And you obviously never have worked with COM ;-) Still +1 for being right on a fundamental level.
David Schmitt
Xsd.exe, unfortunately, doesn't handle all schemas. For some godforsaken reason, it refuses to handle any schema where an element can contain other elements of the same kind, directly or indirectly.
erikkallen
+3  A: 

If you control the definition of the XML (i.e the XSD) than actually writing classes that represent XML is a good idea (these are called DTO's). It gives you a strongly-typed class to code against and you get de-serialization for free without having to do the manual, error-prone parsing of the xml yourself. If this is the case write the classes first, e.g.

[DataContract]
public class Book
{
  [DataMember]
  public string Name {get;set;}

  [DataMember]
  public string Author {get;set;}
}
//Then you can use this code to serialize
var xml = DataContractSerializer.Instance.SerializeToString(
  new Book {Name="A", Artist="B"});

//which will give you something like:
<Book>
<Name>A</Name>
<Author>B</Author>
</Book>
//You can then [Deserialize][2] it back again with:
var book = DataContractDeserializer.Instance.Parse<Book>(xml);

Here are the links to the Serializer and Deserializer classes.

If you have the WSDL or XSD you can use wsdl.exe (or Add Service Reference in VS.NET) or xsd.exe to generate the dto classes for you as @DavidSchmitt suggested.

Alternatively if there is no XSD available then I recommend you take a look at XLinq for another easy way to parse the XML.

mythz
A: 

What you are asking by duck typing is a loose typing, and .net is by all means static typing, at least until the 3.5 version.

if you follow a path of those kinds of though, and type liberation you have: classical frameworks => prototyping frameworks => duck typing.

In js, obviously you can achieve almost all this, but in c# or vb.net, you will find yourself in a classical and bureaucratic, when relating to types.

You can loosely create those types in runtime, but it consumes processing time, and until it is in memory, it can be really slow.

If it is by all means necessary, you have two paths(, involving reflection):

  • You can create those classes, which will be probably a property holder, using property info, and then create a type and insert into it. You will have to create a place to put them into, like a assembly, or a module. you will have little support or no support from your current methods, unless you think in a plan of action for that, and be worried of the security issues it can imply.

  • You can follow the most painful path and use reflection.emit, to create your type straight way in the CLR, which can grant you many, many advantages. It can prove itself a pain to do it though.

If you find a way, please, I would love to hear about it, because duck typing it is great. And independent and brave people have to be praised.

Good Luck to you

NoProblemBabe
+3  A: 

VB.NET allows you to work with XML in a quite intuitive way:

Sub Serialize()
    Dim xml = <myData>
                  <someValue><%= someFunction() %></someValue>
              </myData>
    xml.Save("somefile.xml")
End Sub

Sub Serialize2()   ' if you get the XML skeleton as a string
    Dim xml = XDocument.Parse("<myData><someValue></someValue></myData>")
    xml.<myData>.<someValue>.Value = "test"
    xml.Save("somefile.xml")
End Sub

Sub Deserialize()
    Dim xml = XDocument.Load("somefile.xml")

    Dim value = xml.<myData>.<someValue>.Value
    ...
End Sub

Drawback: You don't have strong typing here; the Value property always returns a string.

Heinzi
This is exactly what I was looking for.
Achilles
Very nice, now my eyes bleed and I won't be able to sleep tonight. :-)
David Schmitt