Should I use Elements or Attributes in XML?

55,437

Solution 1

Usage of attributes or elements is usually decided by the data you are trying to model.

For instance, if a certain entity is PART of the data, then it is advisable to make it an element. For example the name of the employee is an essential part of the employee data.

Now if you want to convey METADATA about data (something that provides additional information about the data) but is not really part of the data, then it is better to make it an attribute. For instance, lets say each employee has a GUID needed for back end processing, then making it an attribute is better.(GUID is not something that conveys really useful information to someone looking at the xml, but might be necessary for other purposes)

There is no rule as such that says something should be an attribute or a element.

Its not necessary to AVOID attributes at all costs..Sometimes they are easier to model, than elements. It really depends on the data you are trying to represent.

Solution 2

My 0.02 five years after the OP is the exact opposite. Let me explain.

  1. Use elements when you're grouping similar data, and attributes of that data.
  2. Don't use elements for everything.
  3. If the data repeats (1 to many), it's probably an element
  4. If the data never repeats, and only makes sense when correlated to something else, it's an attribute.
  5. If data doesn't have other attributes (i.e. a name), then it's an attribute
  6. Group like elements together to support collection parsing (i.e. /xml/character)
  7. Re-use similar element names to support parsing data
  8. Never, ever, use numbers in element names to show position. (i.e. character1, character2) This practice makes it very hard to parse (see #6, parsing code must /character1, /character2, etc. not simply /character.

Considered another way:

  • Start by thinking of all your data as an attribute.
  • Logically group attributes into elements. If you know your data, you'll rarely need to convert attribute to an element. You probably already know when an element (collection, or repeated data) is necessary
  • Group elements together logically
  • When you run into the case the you need to expand, add new elements / attributes based on the logical structure an process above. Adding a new collection of child elements won't "break" your design, and will be easier to read over time.

For example, looking at a simple collection of books and major characters, the title won't ever have "children", it's a simple element. Every character has a name and age.

    <book title='Hitchhiker&apos;s Guide to the Galaxy' author='Douglas Adams'>
        <character name='Zaphod Beeblebrox' age='100'/>
        <character name='Arthur Dent' age='42'/>
        <character name='Ford Prefect' age='182'/>
    </book>

    <book title='On the Road' author='Jack Kerouac'>
        <character name='Dean Moriarty' age='30'/>
        <character name='Old Bull Lee' age='42'/>
        <character name='Sal Paradise' age='42'/>
    </book>

You could argue that a book could have multiple authors. OK, just expand by adding new author elements (optionally remove the original @author). Sure, you've broken the original structure, but in practice it's pretty rare, and easy to work around. Any consumer of your original XML that assumed a single author will have to change anyway (they are likely changing their DB to move author from a column in the 'book' table to an 'author' table).

<book title='Hitchhiker&apos;s Guide to the Galaxy'>
    <author name='Douglas Adams'/>
    <author name='Some Other Guy'/>
    <character name='Zaphod Beeblebrox' age='100'/>
    <character name='Arthur Dent' age='42'>
    <character name='Ford Prefect' age='182'/>
</book>

Solution 3

Not least important is that putting things in attributes makes for less verbose XML.

Compare

<person name="John" age="23" sex="m"/>

Against

<person>
    <name>
        John
    </name>
    <age>
        <years>
            23
        </years>
    </age>
    <sex>
        m
    </sex>
</person>

Yes, that was a little biased and exaggerated, but you get the point

Solution 4

I've used Google to search for the exact question. First I landed on this article, Principles of XML design - When to use elements versus attributes. Though, it felt too long for a simple question as such. Anyhow, I've read through all the answers on this topic and didn't find a satisfactory summary. As such, I went back to the latter article. Here is a summary:

When do I use elements and when do I use attributes for presenting bits of information?

  • If the information in question could be itself marked up with elements, put it in an element.
  • If the information is suitable for attribute form, but could end up as multiple attributes of the same name on the same element, use child elements instead.
  • If the information is required to be in a standard DTD-like attribute type such as ID, IDREF, or ENTITY, use an attribute.
  • If the information should not be normalized for white space, use elements. (XML processors normalize attributes in ways that can change the raw text of the attribute value.)

Principle of core content

If you consider the information in question to be part of the essential material that is being expressed or communicated in the XML, put it in an element. If you consider the information to be peripheral or incidental to the main communication, or purely intended to help applications process the main communication, use attributes.

Principle of structured information

If the information is expressed in a structured form, especially if the structure may be extensible, use elements. If the information is expressed as an atomic token, use attributes.

Principle of readability

If the information is intended to be read and understood by a person, use elements. If the information is most readily understood and digested by a machine, use attributes.

Principle of element/attribute binding

Use an element if you need its value to be modified by another attribute. [..] it is almost always a terrible idea to have one attribute modify another.

This is a short summary of the important bits from the article. If you wish to see examples and full description of every case, then refer to the original article.

Solution 5

Attributes model mapping. A set of attributes on an element isomorphizes directly onto a name/value map in which the values are text or any serializable value type. In C#, for instance, any Dictionary<string, string> object can be represented as an XML attribute list, and vice versa.

This is emphatically not the case with elements. While you can always transform a name/value map into a set of elements, the reverse is not the case, e.g.:

<map>
   <key1>value</key1>
   <key1>another value</key1>
   <key2>a third value</key2>
</map>

If you transform this into a map, you'll lose two things: the multiple values associated with key1, and the fact that key1 appears before key2.

The significance of this becomes a lot clearer if you look at DOM code that's used to update information in a format like this. For instance, it's trivial to write this:

foreach (string key in map.Keys)
{
   mapElement.SetAttribute(key, map[key]);
}

That code is concise and unambiguous. Contrast it with, say:

foreach (string key in map.Keys)
{
   keyElement = mapElement.SelectSingleNode(key);
   if (keyElement == null)
   {
      keyElement = mapElement.OwnerDocument.CreateElement(key);
      mapElement.AppendChild(keyElement);
   }
   keyElement.InnerText = value;
}
Share:
55,437

Related videos on Youtube

Ibn Saeed
Author by

Ibn Saeed

Learning things

Updated on January 21, 2022

Comments

  • Ibn Saeed
    Ibn Saeed over 2 years

    I am learning about XML Attributes from W3Schools.

    The author mentions the following (emphasis mine):

    XML Elements vs. Attributes

    <person sex="female">
      <firstname>Anna</firstname>
      <lastname>Smith</lastname>
    </person>
    

    <person>
      <sex>female</sex>
      <firstname>Anna</firstname>
      <lastname>Smith</lastname>
    </person>
    

    In the first example sex is an attribute. In the last, sex is an element. Both examples provide the same information.

    There are no rules about when to use attributes and when to use elements. Attributes are handy in HTML. In XML my advice is to avoid them. Use elements instead.

    Avoid XML Attributes?

    Some of the problems with using attributes are:

    • attributes cannot contain multiple values (elements can)
    • attributes cannot contain tree structures (elements can)
    • attributes are not easily expandable (for future changes)

    Attributes are difficult to read and maintain. Use elements for data. Use attributes for information that is not relevant to the data.

    So is the view of the author a famous one, or is this the best practice in XML?

    Should Attributes in XML be avoided?

    W3Schools also mentioned the following (emphasis mine):

    XML Attributes for Metadata

    Sometimes ID references are assigned to elements. These IDs can be used to identify XML elements in much the same way as the ID attribute in HTML. This example demonstrates this:

    <messages>
      <note id="501">
        <to>Tove</to>
        <from>Jani</from>
        <heading>Reminder</heading>
        <body>Don't forget me this weekend!</body>
      </note>
      <note id="502">
        <to>Jani</to>
        <from>Tove</from>
        <heading>Re: Reminder</heading>
        <body>I will not</body>
      </note>
    </messages>
    

    The ID above is just an identifier, to identify the different notes. It is not a part of the note itself.

    What I'm trying to say here is that metadata (data about data) should be stored as attributes, and that data itself should be stored as elements.

  • Ibn Saeed
    Ibn Saeed almost 15 years
    I would be using XML with PHP and MySQL. Mainly, on grounds of creating Charts or passing the data to a desktop application for manipulation.
  • John Saunders
    John Saunders almost 15 years
    The standard way to do lists in attributes is attribute="1 2 3 7 20", which is supported by XML Schema.
  • Brian Agnew
    Brian Agnew almost 15 years
    i.e. whitespace separated ? I didn't know that. Now, can I extract those using (say) XPath and other standard toolings ?
  • Ibn Saeed
    Ibn Saeed almost 15 years
    but doesnt using attributes also make it more complex, if not verbose.
  • Nathan Koop
    Nathan Koop almost 15 years
    @Ibn Saeed, I don't think it's more complex. It's as easy to grab an attribute from XML or an element.
  • William Walseth
    William Walseth over 9 years
    If you're building with DOM, the putting single,double quotes isn't a problem in attributes. If you're building XML as a string, then you're open to this an tons of other problems.
  • William Walseth
    William Walseth over 9 years
    I agree, especially with very large documents, all that whitespace makes them really hard to read.
  • dbasnett
    dbasnett over 8 years
    What if you need to include John's five children and their ages?
  • gbjbaanb
    gbjbaanb almost 8 years
    @dbasnett then you create a child element for each child under the single <person> element. The two are not exclusive. If you think of an element as a 'object' and attributes as 'data points' in that object, then its easy to decide when to use each.
  • dbasnett
    dbasnett almost 8 years
    Following the information provided in the link has saved me a lot of headaches. Yes it produces more verbose XML but it is worth it. Follow these principles and it is hard to go wrong.
  • William Walseth
    William Walseth over 3 years
    2 other classics to avoid. 1) NEVER name an element name <attribute>. 2) Avoid the following. <attribute name='Name' value='Douglas Adams'/>, use <author name='Douglas Adams'/>. Sheesh.
  • Bip901
    Bip901 about 3 years
    Attributes are not just for metadata - they're used for any kind of data that isn't hierarchical. See William Walseth's answer.
  • fabspro
    fabspro over 2 years
    Perhaps off-topic, but if you were using the superior SGML then using elements is actually less verbose because you can make the end tags optional!