views:

208

answers:

8
+3  Q: 

Is this good XML?

Hi all,

I'm working for a client who's been using this XML structure for his website's content:

<section title="title1" layoutType="VideoViewer" xmlPath="xml/ita/title1.xml" pageTitle="extended title" previewImg=""/>

<section title="another title" layoutType="TimeLine" xmlPath="xml/ita/timeline.xml" textFile="" pageTitle="extended title for timeline"></section>

I'm quite new to XML, but this doesn't look good to me. Aside from the different way of closing tags (autoclosing with /> or explicitly closed with </section>) I would have thought XML should be more like

<section> 
  <title>title1</title> 
  <layoutType>"VideoViewer" </layoutType>
  <xmlPath>xml/ita/title1.xml </xmlPath> 
  <pageTitle>extended title</pageTitle> 
  <previewImg/>
</section>

<section>
 ...etc etc..
</section>

What do you think?

If they are both OK, is there a "best practice"?

+6  A: 

As long as all of the elements are enclosed within a single root element, there's nothing actually wrong with it.

Either style of closing tag is acceptable, although I would recommend self-closing tags for all elements that don't have other tags inside of them.

As for the structure (tags vs attributes), that's a matter of opinion, neither option is better by definition.

SLaks
Sorry, but -1 for "by definition" since you're not correct.The example with elements, not attributes, is better for extensibility. Elements can have complex content, attributes cannot. If there's any chance that someday there might be, for example, `<maintitle>` and `<subtitle>` components to `<title>`, it would be better to go with an element instead of an attribute representation.
Tenner
@Tenner - your point on complex content is valid, but a schema change is still a schema change so I don't buy your *title* example (unless it starts as a collection of *title*). As SLaks says, there ares two options and there are pro and con for both. I like Eineki's comment, which I'd simplify as: *Elements are objects, attributes are properties.* And yes, I've seen both option overused (200+ char attribute strings, IIRC).
NVRAM
@NVRAM - I agree; if an element changes from simple text to a complex type in its own right, this is likely to cause any existing code to fail
oxbow_lakes
@NVRAM, @oxbow_lakes - I do admit my example was a bit contrived, but it was the best I could do on only a single cup of coffee. :-)My gut likes the element solution and not the attribute solution; I was just taking exception to @SLaks' statement that the two were equivalent _by definition_.
Tenner
+3  A: 

Why do you think XML should be more like that? The first one is attribute-centric; what you're proposing is element-centric. Although nowadays element-centric has become more commonly used, there's certainly nothing wrong with the attribute-centric approach, and it can make some things clearer.

As long as the XML has got a namespace, then there's nothing wrong with it.

Greg Beech
+1  A: 

Your method is, in my opinion nicer. The xml attributes (like title="blah") are used to define attributes for that specific tag, but as you get into more complex data structures you want to think more in terms of objects, where the attributes of a tag really just define extra data (like dataTypes, formats, etc).

Your sample is headed in the right direction, but it's all about how you choose to model your data.

Something like "type" for example might be an appropriate attribute of the section (it's hard to know without knowing exactly what your'e modelling) but I'd assuming something like would be appropriate

brad
+1  A: 

As you openly admit you are new to XML I will point you in the direction of W3 Schools. As for your question, there really is no right or wrong answer both are plausible. It is down to your own particular preference.

James
+3  A: 

Both of them are correct. It is just a matter of personal taste.

I would spend some words on my point of view.

When I was taught XML I've learned that an attribute is preferable to a child element when you have to store a simple property. For simple I mean a single, non structured property.

The non structured part is simple: an attribute can be represented as a string. For single I mean that you can't assign more than a value to a property but you can repeat the same child element to create a set/collection inside the father node.

I would like to be more clear but I'm not so proficient in English to explain better my thought on the subject.

Eineki
Your English is fine. I'd change one bit, though: "an element *can be represented as* a string" (not *is*).
NVRAM
+1  A: 

The auto-closing tag is great, but I don't think using all attributes would be considered 'best practice'. Attributes have more limitations than elements.

From w3schools:

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.

...

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.

Use elements.

mr.moses
+1  A: 

My personal style of designing XML dialects involves a mix of both attributes and elements, heavy on the elements. My general rule of thumb is that no element should exceed 80 characters per line (not including leading whitespace), and thus should never require line wrapping to read comfortably.

I use attributes for brief items that are very specific to the element they're attached to and have no chance of being extended into multiple values. I tend to make booleans, numerical values, and enumerated values attributes. For example, for an image reference element, I'd make the width, height, and format attributes.

I use elements for longer values (particularly ones that conceivably could be of any length), particularly those that may be extended later into a more complex structure. For example, for an image reference element, I'd make the title, caption, description, URL, and other potentially lengthy free-text values child elements of the image reference element.

XML should be easily human-readable. XML dialects should be robust, and not break the system when modified. When in doubt, use elements.

deborah
+2  A: 

I see nothing wrong with the use of attributes in that sample XML. Attributes have a number of limitations that elements don't, and a couple of significant advantages.

First, the limitations:

  • Attributes may only contain simple content.
  • Attribute names must be unique within an element.
  • By definition, the ordering of attributes is not significant in XML; you can't rely on the DOM to iterate over or save attributes in any specific order.
  • Attributes aren't nodes, which means that there are some eccentricities in how you access them in XPath (e.g., the pattern node() | @* used in the XSLT identity transform) and in the DOM (e.g. in .NET, XmlAttribute derives from XmlNode even though attributes aren't nodes, and XmlAttributeCollection doesn't derive from XmlNodeList even though it's a list of XmlNode objects - there are good reasons for this, but it's pretty confusing if you're new to it).

The significant advantages:

  • Because attribute names must be unique within an element, and can only contain simple content, the DOM methods to set and get attribute values are significantly simpler to use than the DOM methods for setting and getting values within elements.
  • Because attribute ordering is not significant, there's no need for code that creates and uses attributes to be concerned with their ordering.
  • Because attributes may only contain simple content, it's easier to write schema definitions for them.
  • The markup for attributes is more concise than the markup for elements.

Attributes isomorphize onto maps/dictionaries very cleanly. You can use attributes as the persistable form of any data structure consisting of name/value pairs, so long as it's OK to restrict the names to valid XML names and the values to text - and so long as when you construct the data structure it doesn't matter what order you populate it in.

(This can cause big problems. In WPF, you can use attributes in XAML to store the values of object properties that have side effects when they're set. Doing this makes for bugs that are freakishly difficult to diagnose - just because you set Binding in your XAML before you set SelectedItem doesn't mean that the XamlReader is going to do that when it constructs the object that your XAML represents, and if it tries to set SelectedItem on an object that doesn't have a Binding yet it'll throw an exception. You can look at your XAML all day long and not see why that's happening.)

In code, the benefits of using attributes are self-evident. To set and get the value of a foo attribute on an element using the XmlDocument DOM (in C#):

elm.SetAttribute("foo", value);

value = elm.GetAttribute("foo");

To set and get the value of a foo element on an element:

XmlElement fooElm = (XmlElement)elm.SelectSingleNode("foo");
if (fooElm == null)
{
   elm.OwnerDocument.CreateElement("foo");
   elm.AppendChild(fooElm);
}
fooElm.InnerText = value;

XmlElement fooElm = (XmlElement)elm.SelectSingleNode("foo");
value = fooElm != null ?? fooElm.InnerText : "";

There are certainly more efficient ways to do the above (write helper methods, use XDocument instead of XmlDocument, or avoid the DOM completely and use serialization), but it's inherently more complex to work with elements.

In your example, it's probably OK to use attributes; it looks like they represent a simple name/value pair mapping with insignificant ordering. The exception might be the titles; if it's ever desirable to allow them to contain markup, you'll come to grief.

Edit:

Actually, I believe the XamlReader will process attributes in the order they appear in the XAML, so if you set Binding before SelectedItem in your XAML it probably won't cause an exception - so long as the XamlReader is reading from the actual text of the XAML. The risk is really that tools that read and write XML documents will alter the ordering of attributes in a XAML document. Does KaXaml preserve the order of attributes in the XAML documents it edits? It shouldn't have to.

At any rate, the solution in XAML is simple: instead of doing this:

<ListBox Binding="{...}" SelectedItem="..." ... />

do this:

<ListBox>
   <ListBox.Binding>...</ListBox.Binding>
   <ListBox.SelectedItem>...</ListBox.SelectedItem>
   ...
Robert Rossney