Lesson 3 of 6

Attributes & Namespaces

Elements aren't the only way to attach data to a tag. Think of an attribute as a sticky note on the outside of a box, versus a child element, which is more like putting a smaller labelled box inside the bigger one. Both can carry "the same" piece of information — the trick is knowing which one you actually want.

💡 The Bottom Line

Attributes are name="value" pairs written inside an opening tag, used for metadata about an element. Child elements represent the element's actual content. Namespaces (the xmlns attribute) exist so that tag names from two different XML vocabularies can be combined into one document without their names colliding.

Attributes: name="value" inside the tag

<book id="123" lang="en">
  <title>The Pragmatic Programmer</title>
</book>

Here id and lang are attributes of the <book> element — they live inside the opening tag itself, as name="value" pairs separated by spaces. Attribute values must always be quoted (single or double quotes both work, but be consistent), and an element can have any number of them.

Attribute or child element — same data, different container

These two fragments arguably represent "the same" fact — that this book has id 123 — but they're structured completely differently:

As an attribute

<book id="123">
  <title>...</title>
</book>

As a child element

<book>
  <id>123</id>
  <title>...</title>
</book>

🔑 Key Distinction: which one should I use?

There's no hard technical rule — XML allows either — but convention leans one way:

  • Attributes for metadata, identifiers, and things that describe an element without being "content" a reader cares about — an id, a lang code, a version number.
  • Child elements for the actual content — the data the document is about, especially anything that might need its own structure, repeat, or contain further nested markup.

A rough test: if you'd ever need to search, sort by, or nest further structure inside a piece of data, it probably belongs as an element, not an attribute.

🙋 There Are No Dumb Questions

Q: Can an attribute's value contain another element?
A: No — attribute values are always plain text (a quoted string), never markup. If you need structure, that's your signal to use a child element instead.

Namespaces: avoiding tag name collisions

What happens when you combine XML from two different vocabularies into a single document, and both vocabularies happen to define a tag with the same name, meaning different things? For example, an HTML document that embeds an SVG image — both HTML and SVG have historically used some overlapping tag names. Without something to disambiguate them, a parser wouldn't know which "meaning" of the tag was intended.

The xmlns attribute solves this by tagging a set of elements with a namespace — a unique identifier (usually a URL, though it's never actually fetched — it just needs to be unique) that says "these tags belong to this specific vocabulary":

<html xmlns="http://www.w3.org/1999/xhtml">
  <body>
    <svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
      <circle cx="50" cy="50" r="40" />
    </svg>
  </body>
</html>

Everything inside the <svg> element is understood to belong to the SVG namespace, even though it's nested inside an HTML document. A parser (or a human) can tell exactly which vocabulary's rules apply to <circle>, without any ambiguity.

⚠️ Watch Out

You'll often see a namespace prefix instead of a default namespace, like <svg:circle> declared with xmlns:svg="...". The prefix itself is arbitrary — it's just a local shorthand for that document. What actually identifies the namespace is the URL/URI value, not the prefix text.

🔧 Try It Yourself

Open any .svg file in a text editor. Look for the xmlns attribute on the root <svg> element — that's the exact mechanism from this lesson, declaring "everything in this document belongs to the SVG vocabulary."

✅ Quick Check

What problem do XML namespaces solve?


Next up: a direct, head-to-head comparison of XML and JSON — where each one is genuinely better, and why.

← Back to
Next →