Comparison
Attributes vs child elements
The oldest argument in XML, and the only parts of it that are not taste: attributes cannot repeat, cannot nest, and cannot be extended later.
Most of the debate is aesthetic and unwinnable. Three differences are not. An element may appear many times and an attribute may appear once; an element may contain structure and an attribute may only contain a string; and an element can grow children in a later version of your format while an attribute can only ever be replaced.
That last one is the practical rule. If there is any chance the value will one day need a qualifier — a currency, a unit, a source, a language — it wants to be an element, because adding a child to an element is backwards compatible and turning an attribute into an element is not.
The counter-case is real too: attributes are the natural home for identifiers and metadata about the element rather than content of it, and they are noticeably cheaper to read in a document dense with them.
What actually differs
| Aspect | Attribute | Child element |
|---|---|---|
| Repeats | Never — one per element | Any number |
| Structure | A string, always | Any subtree |
| Order | Not significant; a canonicalizer sorts them | Significant, and part of the data |
| Namespace | In none unless prefixed, even under a default | In the default namespace |
| Whitespace | Normalized before you see it | Preserved exactly |
| Extending later | Cannot gain structure without a breaking change | Can gain children compatibly |
| In JSON | By convention only, usually a prefixed key | A key, naturally |
Shown, not asserted
The differences above are claims, so here they are being made. Every one of these runs on each test run, against the same engines the tools use — the outputs are what came back, not what we expected.
An attribute cannot repeat. This is not a schema rule — it is a well-formedness error.
document.xml <line sku="W-1" sku="W-2"/>What came back
Attribute sku redefined (line 1)As child elements, the same two values are unremarkable.
document.xml <line><sku>W-1</sku><sku>W-2</sku></line>What came back
Well-formed. Attribute accepts it.And the difference survives conversion: repeated elements become an array, which an attribute could never have been.
document.xml <line><sku>W-1</sku><sku>W-2</sku></line>What came back
json { "line": { "sku": [ "W-1", "W-2" ] } }
Which to pick
Attribute, when
- The value identifies the element rather than being its content: an id, a type, a href.
- It is a single token that will never need qualifying, and never repeat.
- The document is dense and readability would suffer from another level of nesting.
Child element, when
- The value might one day need a qualifier — a currency, a unit, a language, a source.
- It can repeat, or it can carry structure.
- Whitespace inside it matters, since attribute values are normalized before anything sees them.
Where it reaches
- Parse errorsAttribute redefinedThe message a duplicated attribute produces.
- DatatypeswhiteSpaceWhat happens to whitespace in a value, and when.
- ToolsXML to JSON converterThe converter used above, on your own document.
Related comparisons
- XML vs JSONJSON won the API era and XML still runs the documents. The difference that decides it is not verbosity — it is that JSON has no way to represent text interleaved with structure.
- XML vs HTMLThey look alike and behave in opposite ways: HTML forgives everything, XML forgives nothing. Feeding one to the other's parser is the most common way this bites.
Get started
Bring order to the XML your team can't afford to ignore.
Create a free account and get a private workspace to search, validate, diff, and monitor your XML feeds, sitemaps, schemas, and vendor integrations.