XML: A Complete Developer Guide to Structure, XPath, and Validation
Master XML syntax, namespaces, DTD and XSD validation, XPath queries, and understand when to use XML vs JSON in your projects.
By Belqassim Djafer · Published · Updated
What Is XML?
XML (eXtensible Markup Language) is a flexible text format for storing and transporting structured data. Unlike HTML, XML has no predefined tags — you define your own vocabulary. A browser that encounters unknown HTML tags may ignore them; an XML parser rejects malformed XML entirely ("well-formedness" is strictly enforced).
XML was the dominant data interchange format in the 2000s and early 2010s. Today JSON has largely replaced it for REST APIs, but XML remains essential in:
- SOAP web services (many enterprise systems)
- Configuration files (Maven's
pom.xml, Spring'sapplicationContext.xml) - Office formats (DOCX, XLSX, PPTX are ZIP archives containing XML files)
- RSS and Atom feeds
- SVG graphics
- Android resources (
AndroidManifest.xml, layout files)
XML Syntax Rules
Well-Formed XML Requirements
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book id="1" lang="en">
<title>Clean Code</title>
<author>Robert C. Martin</author>
<price currency="USD">35.99</price>
<available/>
</book>
<book id="2" lang="fr">
<title>Le Petit Prince</title>
<author>Antoine de Saint-Exupéry</author>
<price currency="EUR">9.99</price>
</book>
</bookstore>
Rules that must be followed:
- Single root element: every XML document has exactly one root
- Tags must close:
<br />or<br></br>; HTML's unclosed<br>is invalid XML - Case-sensitive:
<Book>and<book>are different tags - Attribute values must be quoted:
id="1"notid=1 - Proper nesting:
<a><b></b></a>not<a><b></a></b>
Special Characters
<!-- 5 predefined entities -->
& → &
< → <
> → >
" → "
' → '
<!-- CDATA section: content not parsed -->
<description><![CDATA[x < y && y > 0]]></description>
Namespaces
Namespaces prevent element name conflicts when XML from different vocabularies are combined:
<?xml version="1.0"?>
<root
xmlns:h="http://www.w3.org/TR/html4/"
xmlns:f="https://www.example.com/furniture">
<h:table>
<h:tr><h:td>HTML table cell</h:td></h:tr>
</h:table>
<f:table>
<f:name>African Coffee Table</f:name>
<f:width>80</f:width>
</f:table>
</root>
The namespace URI is just a unique identifier — it doesn't need to resolve to anything.
XML Schema Validation
DTD (Document Type Definition)
DTD is the older validation format, still widely used:
<!DOCTYPE bookstore [
<!ELEMENT bookstore (book+)>
<!ELEMENT book (title, author, price)>
<!ATTLIST book id ID #REQUIRED>
<!ELEMENT title (#PCDATA)>
<!ELEMENT author (#PCDATA)>
<!ELEMENT price (#PCDATA)>
]>
XSD (XML Schema Definition)
XSD is more powerful, expressed in XML itself, and supports data types:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="bookstore">
<xs:complexType>
<xs:sequence>
<xs:element name="book" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="author" type="xs:string"/>
<xs:element name="price" type="xs:decimal"/>
</xs:sequence>
<xs:attribute name="id" type="xs:positiveInteger" use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
XPath: Querying XML
XPath is a query language for selecting nodes from an XML document:
/bookstore/book Select all book elements directly under bookstore
//book Select all book elements anywhere in the document
//book[@id='1'] Book with attribute id='1'
//book/title/text() Text content of all title elements
//price[@currency='USD'] Prices in USD
//book[price > 10] Books costing more than 10
count(//book) Count of all books
//book[last()] Last book element
//book[position() < 3] First two books
XPath in Programming Languages
import xml.etree.ElementTree as ET
tree = ET.parse("bookstore.xml")
root = tree.getroot()
# Find all book titles
for title in root.findall(".//title"):
print(title.text)
# Find books over 20 USD
for book in root.findall(".//book"):
price = float(book.find("price").text)
if price > 20:
print(book.find("title").text)
// Browser DOM / DOMParser
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(xmlString, "text/xml");
const titles = xmlDoc.evaluate(
"//title",
xmlDoc,
null,
XPathResult.ANY_TYPE,
null
);
let result = titles.iterateNext();
while (result) {
console.log(result.textContent);
result = titles.iterateNext();
}
XML vs JSON: When to Use Each
| Feature | XML | JSON |
|---|---|---|
| Comments | ✅ <!-- comment --> |
❌ |
| Attributes | ✅ <tag attr="val"> |
❌ (nested object only) |
| Mixed content | ✅ text + child elements | ❌ |
| Schema validation | ✅ DTD, XSD, RelaxNG | JSON Schema (less mature) |
| Namespaces | ✅ | ❌ |
| Verbosity | Higher | Lower |
| Parsing speed | Slower | Faster |
| Browser support | DOM API | Native JSON.parse |
Choose XML when:
- Working with SOAP, RSS/Atom, SVG, or DOCX/XLSX
- Needing namespaces or mixed content
- Integrating with enterprise systems that require XSD validation
Choose JSON when:
- Building REST APIs
- Storing simple structured data
- Working in modern JavaScript environments
XSLT: Transforming XML
XSLT (Extensible Stylesheet Language Transformations) transforms XML into HTML, other XML, or plain text:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html><body>
<h1>Books</h1>
<xsl:for-each select="bookstore/book">
<p><xsl:value-of select="title"/> — <xsl:value-of select="author"/></p>
</xsl:for-each>
</body></html>
</xsl:template>
</xsl:stylesheet>
Use our XML to JSON converter and JSON to XML converter to transform between formats, and our XML Compare tool to diff two XML documents.
Conclusion
XML remains a critical technology despite JSON's dominance. Understanding its strict well-formedness rules, namespace system, XSD validation, and XPath querying is essential for anyone integrating with enterprise APIs, SOAP services, or document formats like DOCX and SVG. Use the right format for the job — and the tools above when you need to convert between them.