What's an elegant and easy way to construct XML from a custom object?
I need to construct an XML transaction of the following format:
<RateV3Request USERID="MyId">
<Package ID="1ST">
<Service>ALL</Service>
<FirstClassM开发者_开发问答ailType>LETTER</FirstClassMailType>
<ZipOrigination>06226</ZipOrigination>
<ZipDestination>06231</ZipDestination>
<Pounds>0</Pounds>
<Ounces>4.5</Ounces>
<Size>REGULAR</Size>
<Machinable>true</Machinable>
<ShipDate Option="EMSH">21-Dec-2009</ShipDate>
</Package>
</RateV3Request>
My thought was to create an object RateV3Request that contains typed properties for each XML property (I assume property is not the correct word here.)
I was thinking of creating a "GetXml" function on my object that returns the XML representation of the values in the object instance.I could do all the string concatenation myself, but surely there is a cleaner way.
Suggestions? I am using VB.NET
The XmlSerializer should do this work for you. You can use XML attributes to control how your properties and fields should be serialized to XML (e.g. as an attribute, as a specific element, not at all, ...).
For example, your Package
class could look like this (untested):
Public Class Package
<XmlAttribute("ID")> _
Public Property ID As String
...
End Property
Public Service As String
...
End Class
Then you can do something like this (untested):
Dim packageSerializer As New XmlSerializer(GetType(Package))
Dim writer As New StringWriter()
packageSerializer.Serialize(writer, myPackage)
Console.WriteLine(writer.ToString())
XML Terminology:
In XML, you have elements and attributes. In your example, ZipOrigination
is an element--it contains an opening and closing tag. USERID
is an attribute--it appears in the opening tag of an element and has a name and value (which is in quotes).
.NET Framework classes
For your particular problem, you could use either an XDocument
(http://msdn.microsoft.com/en-us/library/system.xml.linq.xdocument.aspx) or an XmlDocument
(http://msdn.microsoft.com/en-us/library/system.xml.xmldocument.aspx). XDocument
is a more recent addition to the .NET framework, and for many tasks, it is the preferred choice. See this thread, for example: http://social.msdn.microsoft.com/forums/en-US/xmlandnetfx/thread/4895ba4d-0425-4d10-9bae-5c33e8385357.
Custom classes
It looks like you would want to write a class RateV3Request
that contains properties UserId
and Package
. It looks like another class ShipDate
with the property Option
might be useful. Then, finally, you could write a class Package
that contains all the remaining properties (Id, Service, FirstClassMailType, ..., ShipDate). Each property should have the appropriate data type.
Putting it all together
You could either add a GetXml()
method for each of your custom classes or you could write a dedicated class (e.g., RateV3RequestGateway
) that handles all the conversion between your classes and XML. I tend to prefer the dedicated class because it provides more flexibility. If later, you wanted to use a database or JSON instead of XML, you could write a different gateway but wouldn't have to touch your custom classes.
Two options worth considering for creating XML:
Serialization - built in and if needed you've got some control over how exactly the serializer works.
Hand craft stuff (and this isn't necessarily a bad option as it lets you produce exactly what you want) then you want to work with Linq to XML - there's some really clever stuff in VB.NET to make this almost declarative (though I haven't played as my language of choice is currently C#).
Given your basic requirement - which is to produce XML to pass to another application I would probably be more likely to go with Hand Crafted given how easy it is to create using the various Linq to XML constructs.
If hand crafting this then gives you more flexibility in crafting your model objects - you can get them right for your application and then use either a method or a helper class to generate the XML - more often than not we have a wrapper for a service that takes our model classes and generates the required XML in close proximity to the service call. Not sure how good a pattern this is... but we've found it to be effective.
Most current OOP languages that support XML will have a serialization library that will handle that kind of thing for you.
In general the idea is that the serialization library will reflect over your object and construct the XML from it, sometimes you may need to provide some hints for it. In .NET the hints will be in the form of attributes you use to decorate the different properties of your object.
For .NET, you can look at the serialization namespace.
精彩评论