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, alangcode, aversionnumber. - 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.