views:

206

answers:

4

I'm designing an API for a web service and I can't decide between using XML attributes, elements or a mixed architecture.

Let me show you an example. Let's assume I have an object called Domain. This model has 3 properties (tld, sld, trd and the name itself) and a method valid? that returns true if the domain is valid.

# I'm using ruby but 
# consider this as pseudo-code
class Domain
  attr_accessor :tld, :sld, :trd, :name

  def valid?
    true # force true
  end
end

My api called /domain/parser takes a domain in input and returns the parsed response. The first possibility is to use an element for every domain attribute.

<result>
  <domain>
    <name>www.google.it</name>
    <tld>it</tld>
    ...
    <valid>true</true>
  </domain>
</result>

But some interfaces use attributes.

<result>
  <domain tld="it" sld="google.com" trd="www" rule="*.foo" name="www.google.it" valid="true" />
</result>

And don't forget attributes and value.

<result>
  <domain tld="it" sld="google.com" trd="www" rule="*.foo" name="www.google.it" valid="true">
    www.google.it
  </domain>
</result>

In your opinion, which is the more powerful, flexible and expressive choice? Also, consider the response will be served in XML and JSON (soon).

+3  A: 

WCF's designers chose to avoid attributes, mostly for performance reasons. The WCF default serializer, the DataContractSerializer, doesn't support attributes (so that might be something to take into consideration), but it's roughly 10% faster than the more flexible XmlSerializer in .NET.

So if you ever see yourself serving up content to be consumed by a WCF client, you will likely try to steer clear of attributes, if ever possible.

Attributes are only ever going to be "atomic", e.g. a string, an int etc. - elements offer much more flexibility that way. Also, attributes never exist on their own - they're always tacked onto an element.

From my personal experience and personal preference, I would most likely try to use mostly elements and avoid attributes as much as I can. But that's really just a personal preference and taste - attributes are absolutely valid in XML, no problem.

marc_s
This is odd! So you are telling me, for example, the FeedBurner API is incompatibile with WCF? http://code.google.com/apis/feedburner/awareness_api.html
Simone Carletti
@weppos: no - if the WCF svcutil utility detects any attributes in an XML, it will switch back to the (slower, legacy) XmlSerializer instead.
marc_s
+2  A: 

It's mainly a matter of taste, but there are some technical considerations. Attributes are slightly more restricted in what characters they can contain. They have the ?advantage? that order is immaterial but they cannot be repeated. This may slightly influence your choice according to what toolset you have

peter.murray.rust
Technically attributes can contain exactly same characters, just need to quote slightly different set of characters.
StaxMan
True in principle - but it would be a lot of work and unnatural to avoid whitespace normalization.
peter.murray.rust
+4  A: 

The pattern I use is:

  • elements are for data
  • attribute are for meta data (i.e. data about the data)

if you use XSD schema's most if not all of your meta data should go in there, but if you don't attributes are good place for it.

So with your example I might do something like this:

<result>
  <domain valid="true">
    <name>www.google.it</name>
    <tld>it</tld>
    ...
  </domain>
</result>
dkackman
+1  A: 

If your data can be thought of as having two levels, where one is the core data and the other is some sort of metadata (e.g. labels for certain elements) then you might want to use elements for the former and attributes for the latter, e.g.:

<result id="1">
  <domain type="default">
    <name unique="false">www.google.it</name>
    <tld>it</tld>
    ...
    <valid>true</true>
  </domain>
</result>

Typically if you strip all the attributes out the remaining data still looks meaningful.

Another rule i sometimes use is attributes for summary data and elements for the rest. Then if i want to sent a summary list for instance i just send the top element plus its attributes and leave out the contained elements. E.g.

<result>
  <domain name="www.google.it">
    <tld>it</tld>
    ...
    <valid>true</true>
  </domain>
</result>

which in a list becomes:

<results>
  <domain name="www.google.it">
  <domain name="www.google.co.uk">
  <domain name="www.google.com">
</results>

Alternatively if neither of those cases apply then you might just want to use elements for anything that has internal structure or where the order is important, and attributes for everything else, as per your second XML example.

jon hanson