8

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).

Daniel Rikowski
  • 71,375
  • 57
  • 251
  • 329
Simone Carletti
  • 173,507
  • 49
  • 363
  • 364
  • 1
    Others have answered main points; but one additional note is that the question of alternative JSON representation should be orthogonal to XML representation. That is, your choice of elements vs attributes should not have any effect on how JSON should be structured. Since XML and JSON differ structurally, you should not convert between the two: rather, produce them separately but from same object that you have. This allows both representations to be "optimal", as in not being forced to use mappings to overcome limitations (which is done by some JSON mappings, to convert from XML). – StaxMan Nov 30 '09 at 22:37

4 Answers4

8

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
  • 15,179
  • 13
  • 69
  • 123
5

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
  • 732,580
  • 175
  • 1,330
  • 1,459
  • 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 Nov 30 '09 at 21:57
  • @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 Nov 30 '09 at 22:00
3

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

Lawrence Dol
  • 63,018
  • 25
  • 139
  • 189
peter.murray.rust
  • 37,407
  • 44
  • 153
  • 217
3

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.

Lawrence Dol
  • 63,018
  • 25
  • 139
  • 189
jon hanson
  • 8,722
  • 2
  • 37
  • 61