Last modified: March 23, 2026
This article is written in: πΊπΈ
XML, or Extensible Markup Language, is a W3C-standardized markup language designed to encode documents in a format that is both human-readable and machine-readable. Unlike HTML, which has a fixed set of tags, XML lets you define your own vocabulary of elements to represent arbitrary data structures. It remains widely used in enterprise web services, configuration files, and document interchange where strict schema validation matters.
<!-- ... --> syntax and are ignored by parsers but useful for documenting intent inside the file.<?xml-stylesheet ... ?> give directives to the application consuming the document.<?xml version="1.0" encoding="UTF-8"?> to declare the version and character encoding.<Name> and <name> are treated as different elements.<, >, and & must be written as entity references (<, >, &).Every XML document forms a logical tree rooted at the single root element. Understanding this tree is key to querying and transforming XML.
[document]
|
<employee>
/ | \
<name> <address> <skills>
| / | \ |
"John" <street> <city> <zipCode> <skill> <skill>
| | | | |
"1234.." "Any.." "12345" "Java" "C#"
Below is a complete XML document demonstrating nested elements, attributes, and namespaces:
<?xml version="1.0" encoding="UTF-8"?>
<employee id="E1001" xmlns:hr="http://example.com/hr">
<name>John Doe</name>
<age>30</age>
<hr:department code="ENG">Engineering</hr:department>
<address>
<street>1234 Main St</street>
<city>Anytown</city>
<state>CA</state>
<zipCode>12345</zipCode>
</address>
<skills>
<skill level="senior">Java</skill>
<skill level="mid">C#</skill>
<skill level="junior">Python</skill>
</skills>
</employee>
When multiple XML vocabularies are combined in one document, name collisions can occur. Namespaces solve this by qualifying element and attribute names with a URI.
xmlns:hr="http://example.com/hr" binds the prefix hr to a unique namespace URI.xmlns="...") applies to all unprefixed child elements within its scope.<hr:department> clearly indicate which vocabulary the element belongs to.<root xmlns:app="http://example.com/app"
xmlns:db="http://example.com/db">
<app:config>
<db:connection host="localhost" port="5432"/>
</app:config>
</root>
Validation ensures an XML document conforms to a predefined structure. Two main technologies exist:
XML Document
|
v
+---------------+ +---------------------+
| Well-formed? |--No->| Reject (parse err) |
+-------+-------+ +---------------------+
| Yes
v
+---------------+ +---------------------+
| Valid against |--No->| Reject (validation |
| DTD or XSD? | | error) |
+-------+-------+ +---------------------+
| Yes
v
Accept Document
| Feature | DTD | XSD |
| Syntax | Non-XML, compact grammar | XML-based |
| Data Types | Limited (CDATA, ID, IDREF) | Rich (int, date, regex, etc.) |
| Namespace Support | None | Full namespace awareness |
| Extensibility | Low | High (inheritance, groups) |
| Industry Adoption | Legacy systems | Modern enterprise standards |
XPath is a query language for selecting nodes from an XML document tree. It is used heavily in XSLT, XQuery, and many programming APIs.
/employee/name selects the <name> child using an absolute path from the root.//skill selects every <skill> element anywhere in the document with a recursive descent.//skill[@level='senior'] filters elements by attribute value using a predicate... navigates to the parent of the current node, similar to filesystem paths.text() returns the text content within the matched element.XPath: /employee/address/city
<employee>
|
<address> <-- step 2
|
<city> <-- step 3
|
"Anytown" <-- result
Two dominant strategies exist for reading XML, each with distinct memory and performance trade-offs.
XML Document
|
+---------+---------+
| |
v v
DOM Parser SAX Parser
(tree in RAM) (event stream)
| |
v v
Full node tree Callbacks fired
available for for each start-tag,
random access end-tag, and text
| Aspect | DOM | SAX | StAX |
| Memory | High (full tree in RAM) | Low (event-driven) | Low (pull-based) |
| Access Pattern | Random | Sequential only | Sequential only |
| Ease of Use | Simple navigation API | Callback-heavy | Iterator-style |
| Write Support | Yes (modify and serialize) | Read-only | Read and write |
| Best For | Small docs, editing | Large docs, filtering | Streaming pipelines |
XML parsers can be exploited if they process untrusted input without proper safeguards. The most critical vulnerability is XML External Entity (XXE) injection.
Attacker crafts XML with external entity:
<?xml version="1.0"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<data>&xxe;</data>
Parser Flow:
1. Parser reads DTD --> sees ENTITY declaration
2. Resolves "file://" --> reads /etc/passwd from disk
3. Substitutes &xxe; --> sensitive data in <data> output
XMLConstants.FEATURE_SECURE_PROCESSING to true and disallow doctype declarations.defusedxml instead of the standard library's xml.etree for safe parsing of untrusted data.pom.xml), Spring, and Android manifests use XML for structured settings..docx) are built on XML foundations.encoding="UTF-8" in the XML declaration to avoid character misinterpretation.