Choosing XML Element Names and Casing That Hold Up
XML names are case sensitive and follow strict character rules. Compare camelCase, snake_case and kebab-case for elements, with the rules that decide.

Naming elements looks like a style choice, and mostly it is. But XML has hard rules about what a name can be, a parser that will reject one wrong letter, and downstream tools that turn names into identifiers in code. A convention picked on the first day ends up in schemas, in generated classes and in every consumer's mapping, so it pays to choose with those constraints in mind.
The hard rules
XML names are case sensitive. An element named Order is a different element from order, and the end tag must match the start tag exactly. A one-letter slip is a well-formedness error, and a parser stops there:
from lxml import etree
etree.fromstring("<Order><id>1</id></order>")lxml.etree.XMLSyntaxError: Opening and ending tag mismatch: Order line 1 and order, line 1, column 26The character rules are short. A name starts with a letter or an underscore. After that it may contain letters, digits, hyphens, underscores and periods. It cannot contain spaces, and a colon is reserved for namespace prefixes (how XML namespaces work). It cannot start with a digit, so 2fa is invalid and twoFactor is not. Non-ASCII letters are allowed, so <größe> is legal, but tools in your pipeline may not handle it, and I would avoid it in anything shared.
Names that start with xml in any combination of case are reserved by the specification for its own use. Most parsers accept <xmlData>, and the specification advises against it because future versions of the standard may claim those names. Avoid the prefix; call it payload or data.
Three conventions compared
All three conventions below satisfy the hard rules. They differ in what happens next.
| Convention | Example | Maps to code identifier | Common in |
|---|---|---|---|
| lower camelCase | orderTotal | Directly, in most languages | Java and .NET shops, SOAP, many APIs |
| snake_case | order_total | Directly, in Python, Ruby, SQL | Data feeds, database exports |
| kebab-case | order-total | Needs rewriting | Hand-written configuration, Maven, Spring |
camelCase and snake_case turn into field names with no rewriting. Kebab-case does not: a hyphen is not legal in an identifier in Java, C#, Python, Go or SQL, so a generated class must rename order-total to orderTotal or order_total, and the renaming is another place for a bug. In a Python script, item.order-total is a subtraction; you reach it only through item["order-total"] or find("order-total"). JAXB, xsd.exe and similar generators apply a rule to convert it, usually correctly, and every rule has a corner case such as two names that differ only in hyphen placement.
PascalCase (OrderTotal) is the fourth common choice, used by .NET serializers and many government and financial schemas. It is a fine choice when the main consumer is C#, because properties in that language are conventionally PascalCase and the mapping is trivial. It is a worse choice when the consumers are mixed, because it reads unlike the rest of their code.
How to decide
Choose by the people who will consume the document, not by taste:
Who reads it in code? If one language dominates, use its field naming. If several, snake_case or camelCase are both safe, and snake_case survives a round trip through SQL column names without quoting.
Is there an existing convention in the format family? A Maven file uses kebab-case, an Android manifest uses camelCase attributes. If your document extends or sits beside one, match it.
Will it become JSON? Many XML documents are later converted (converting XML to JSON). A name that is a valid identifier becomes a clean JSON key that code can use directly.
Is it a public contract? Then you cannot rename later without a version change (versioning an XML format without breaking readers). Pick carefully now.
Apply the convention to attributes as well as elements, and to enumerated values if you control them (status="paid" rather than status="PAID" in one place and status="Paid" in another). Mixing styles inside one document, which happens when two teams contribute, is the common failure. A schema makes the convention checkable, because a name outside it directly does not validate.
Names that say what the content is
Casing is the easy part. A good name describes the content and not its position or format:
Name the thing, not the type.
<total>beats<decimalValue1>.Avoid abbreviations that need a glossary.
<cust>saves four letters. Everyone who reads the file pays for it. Abbreviate only what the domain abbreviates, such asskuoriban.Use singular for the item, a plural wrapper for the collection.
<items><item/><item/></items>reads naturally and maps to a list nameditemsofitemobjects (modeling lists and optional data in XML covers wrappers).Do not encode data in the name.
<item1>,<item2>and<item3>mean the structure changes with the data, and a schema cannot describe it. Use one repeating element, with an attribute or child for the index if the position matters.Do not reuse a name for two meanings.
<date>that is a creation time inside<order>and a ship-by day inside<shipment>is fine in separate contexts, and a problem when one XPath//datematches both.
Related reading
The cluster hub is designing XML documents that age well. Choosing between an element and an attribute is a related decision (when attributes are the better choice). The syntax rules are in XML attributes versus child elements, and the cheat sheet in a cheat sheet of XML syntax rules. The grammar for names is in the XML 1.0 specification, and the reserved prefix is explained in section 2.3. Check what a document does to your names with the XML to JSON tool.
When you should not choose the names yourself
You implement an existing standard. If a schema such as UBL, HL7 or a partner's SOAP contract defines the vocabulary, use its names exactly, including its casing, even when you dislike them. Translating costs more than the aesthetics are worth.
The names are generated. If a serializer builds the XML from classes, the names come from the class and member names. Fix them there, with annotations such as @XmlElement(name=...), rather than in a post-processing step.
The document is for people. Prose-oriented formats such as DocBook or XHTML use short lower-case names by convention, and inventing your own camelCase inside them helps nobody.
You are tempted to put units or types in the name. <weightKg> is tolerable until the day someone sends pounds. An attribute (<weight unit="kg">) or a schema type carries that without a rename.


