XML in configuration files
Maven POM, Spring beans, Android layouts, .NET config and Log4j2 — what XML config does well, where it becomes painful, and how to decide between XML and a newer format.
XML config in the wild
<!-- Maven pom.xml: build metadata, dependencies, plugins -->
<project xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>orders</artifactId>
<version>1.4.2</version>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<release>21</release>
</configuration>
</plugin>
</plugins>
</build>
</project><!-- Android layout: XML describes a UI tree, which is a genuine document -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/title" />
</LinearLayout>Both work because the structure is a tree that a human edits by hand and a tool validates. That is the same property that makes XML a good document format, applied to configuration.
What XML config gives and costs
| Aspect | XML config | YAML or TOML |
|---|---|---|
| Validation | XSD, DTD, or a proprietary schema | Usually none, or a separate schema |
| Tooling | Mature editors, XPath queries | Good but newer |
| Verbosity | High — every field is two tags | Low |
| Namespaces | Built in, allows mixing vocabularies | Not available |
| Comments | Supported everywhere | Supported |
| Type inference | None — everything is text | YAML infers; TOML is explicit |
| Merge and override | Often a bespoke mechanism | Often built into the tool |
- The verbosity is not accidental: closing tags make it possible to validate a fragment and to see the structure without counting indentation.
- Namespaces let a plugin extend a base configuration without collisions, which is why plugin-heavy build tools still use XML.
- Everything is text, so a numeric field is a string until the tool coerces it. A validation schema removes most of the resulting problems.
- Deeply nested XML becomes hard to read once indentation passes four or five levels, which is where most teams start looking for alternatives.
Choosing a config format
- Use whatever the tool requires — the format is not a free choice for Maven, Android or Spring XML.
- For your own configuration, prefer a typed format such as TOML when a human edits it.
- Choose XML when you need namespaces, validation against a schema, or XPath queries.
- Keep secrets out of any committed config file; read them from the environment or a secret store.
- If the config is generated rather than edited, generate the simplest format the consumer accepts.
- Validate configuration at startup and fail with a clear message, whichever format you picked.
# query config with XPath instead of grepping
xmllint --xpath '//dependency[groupId="org.junit.jupiter"]/version/text()' pom.xml
# validate before running the build
xmllint --noout --schema pom.xsd pom.xml
# formatted diff of two versions of a config tree
xmllint --format a.xml > a.pretty
xmllint --format b.xml > b.pretty
diff -u a.pretty b.pretty⚠️
Configuration XML is untrusted input if a user can supply it. An external entity declaration in a config file is the classic XXE vector: disable DTD processing and external entities in the parser before you read any configuration you did not ship yourself.
FAQ
Why do Java projects still use XML?
The ecosystem, the tooling and the validation are mature, and namespaces allow composition. The alternative exists, but migration cost keeps the older format in place.
Can I use YAML for a Maven project?
Not for the POM itself. Some plugins accept YAML for their own configuration, but the project model is XML by definition.
Related
Attributes vs child elements: modelling decisions XML security: XXE and entity expansion
Last refreshed 2026-09-18.