Every XML document has one root element. Child elements hold the data. Save this as students.xml.
<?xml version="1.0" encoding="UTF-8"?>
<students>
<student id="1">
<name>Alice</name>
<grade>A</grade>
<score>95</score>
</student>
<student id="2">
<name>Bob</name>
<grade>B</grade>
<score>82</score>
</student>
<student id="3">
<name>Carol</name>
<grade>A</grade>
<score>91</score>
</student>
</students>
Parse the XML string with DOMParser, then use querySelectorAll to loop every <student> element and print its children.
const xmlString = `<?xml version="1.0"?>
<students>
<student id="1"><name>Alice</name><grade>A</grade><score>95</score></student>
<student id="2"><name>Bob</name><grade>B</grade><score>82</score></student>
<student id="3"><name>Carol</name><grade>A</grade><score>91</score></student>
</students>`;
// 1. Parse the string into an XML DOM
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(xmlString, "text/xml");
// 2. Select all <student> elements
const students = xmlDoc.querySelectorAll("student");
// 3. Loop and read values
students.forEach(student => {
const id = student.getAttribute("id");
const name = student.querySelector("name").textContent;
const grade = student.querySelector("grade").textContent;
const score = student.querySelector("score").textContent;
console.log(`ID: ${id} | Name: ${name} | Grade: ${grade} | Score: ${score}`);
});
// Output:
// ID: 1 | Name: Alice | Grade: A | Score: 95
// ID: 2 | Name: Bob | Grade: B | Score: 82
// ID: 3 | Name: Carol | Grade: A | Score: 91
Use an attribute selector in querySelector to find a specific element.
// Find the student whose id attribute equals "2"
const bob = xmlDoc.querySelector('student[id="2"]');
console.log(bob.querySelector("name").textContent); // "Bob"
console.log(bob.querySelector("score").textContent); // "82"
// Read an attribute
console.log(bob.getAttribute("id")); // "2"
// getElementsByTagName — returns an HTMLCollection
const allNames = xmlDoc.getElementsByTagName("name");
for (let i = 0; i < allNames.length; i++) {
console.log(allNames[i].textContent); // Alice, Bob, Carol
}
After parsing, the XML document is a live DOM tree. Update textContent to change element values, then serialize back to a string.
// Change Bob's score from 82 to 88
const bob = xmlDoc.querySelector('student[id="2"]');
bob.querySelector("score").textContent = "88";
bob.querySelector("grade").textContent = "A"; // also upgrade grade
// Verify
console.log(bob.querySelector("score").textContent); // "88"
// Serialize the updated document back to an XML string
const serializer = new XMLSerializer();
const updatedXML = serializer.serializeToString(xmlDoc);
console.log(updatedXML);
// <students>...<student id="2"><name>Bob</name><grade>A</grade><score>88</score></student>...</students>
Use setAttribute() to update an existing attribute, or add a new one.
// Change Alice's id from "1" to "101"
const alice = xmlDoc.querySelector('student[id="1"]');
alice.setAttribute("id", "101");
// Add a new attribute
alice.setAttribute("status", "active");
console.log(alice.getAttribute("id")); // "101"
console.log(alice.getAttribute("status")); // "active"
Create new elements with createElement(), set their content, then appendChild() them into the tree.
// Build the new <student> element
const newStudent = xmlDoc.createElement("student");
newStudent.setAttribute("id", "4");
const newName = xmlDoc.createElement("name");
newName.textContent = "David";
const newGrade = xmlDoc.createElement("grade");
newGrade.textContent = "B";
const newScore = xmlDoc.createElement("score");
newScore.textContent = "78";
newStudent.appendChild(newName);
newStudent.appendChild(newGrade);
newStudent.appendChild(newScore);
// Append to the root <students> element
const root = xmlDoc.documentElement; // <students>
root.appendChild(newStudent);
// Confirm
const all = xmlDoc.querySelectorAll("student");
console.log(all.length); // 4
Use removeChild() on the parent, or the modern element.remove().
// Remove Bob (id="2")
const bobNode = xmlDoc.querySelector('student[id="2"]');
// Option A — remove via parent
bobNode.parentNode.removeChild(bobNode);
// Option B — modern shorthand
// bobNode.remove();
const remaining = xmlDoc.querySelectorAll("student");
console.log(remaining.length); // 2 (Alice and Carol remain)
Real-world pattern: load an XML file from the server, modify the DOM tree in memory, then use the data in your UI.
async function loadAndUpdate(url) {
// 1. Fetch the XML file
const response = await fetch(url);
const text = await response.text();
// 2. Parse
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(text, "text/xml");
// 3. Check for parse errors
if (xmlDoc.querySelector("parsererror")) {
throw new Error("Invalid XML");
}
// 4. Read all students into a JS array
const students = [...xmlDoc.querySelectorAll("student")].map(s => ({
id: s.getAttribute("id"),
name: s.querySelector("name").textContent,
grade: s.querySelector("grade").textContent,
score: Number(s.querySelector("score").textContent)
}));
// 5. Update a value — boost every score by 5
xmlDoc.querySelectorAll("score").forEach(node => {
node.textContent = Number(node.textContent) + 5;
});
// 6. Serialize back to string (e.g. to POST to server)
const updated = new XMLSerializer().serializeToString(xmlDoc);
return { students, updated };
}
loadAndUpdate("/data/students.xml").then(({ students }) => {
students.forEach(s => console.log(s.name, s.score));
});
XML (eXtensible Markup Language) is a markup language designed to store and transport data in a format that is both human-readable and machine-readable. It was defined by the W3C in 1998.
Unlike HTML, XML does not have predefined tags — you define your own tags to describe your data structure.
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book category="fiction">
<title>The Great Gatsby</title>
<author>F. Scott Fitzgerald</author>
<price>12.99</price>
</book>
</bookstore>
An XML document is called well-formed when it follows these rules:
- Every opening tag must have a matching closing tag:
<name>...</name>. - Tags are case-sensitive —
<Book>and<book>are different. - Tags must be properly nested — no overlapping.
- There must be exactly one root element.
- Attribute values must be in quotes (single or double).
- Self-closing tags for empty elements:
<br />.
<!-- ✗ INVALID — overlapping tags -->
<b><i>text</b></i>
<!-- ✓ VALID — proper nesting -->
<b><i>text</i></b>
An element is a tag that can contain text, child elements, or both. An attribute provides additional metadata about an element and lives inside the opening tag.
<!-- Using an attribute -->
<book id="101" category="fiction">
<title>Dune</title>
</book>
<!-- Same data as child elements -->
<book>
<id>101</id>
<category>fiction</category>
<title>Dune</title>
</book>
Best practice: use attributes for metadata (IDs, types) and child elements for data that could grow or be structured.
The XML declaration is the optional first line of an XML document. It tells the parser the XML version and the character encoding used.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
version— always"1.0"for standard XML.encoding— default is UTF-8. Common values: UTF-8, UTF-16, ISO-8859-1.standalone—"yes"means the document does not rely on an external DTD.
It is not required but recommended, especially when using non-UTF-8 encodings.
Comments in XML use the same syntax as HTML:
<!-- This is a comment -->
A CDATA section wraps text that should not be parsed as XML markup. Useful for embedding HTML or code inside XML without escaping every special character.
<description>
<![CDATA[
<p>This <b>HTML</b> won't be parsed as XML</p>
if (a < b && c > d) { ... }
]]>
</description>
A DTD (Document Type Definition) defines the legal building blocks of an XML document — which elements are allowed, their order, and their attributes. An XML document that conforms to its DTD is called valid.
<!-- Internal DTD -->
<?xml version="1.0"?>
<!DOCTYPE note [
<!ELEMENT note (to, from, message)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT message (#PCDATA)>
]>
<note>
<to>Alice</to>
<from>Bob</from>
<message>Hello!</message>
</note>
XSD (XML Schema Definition) is the W3C standard for describing and validating the structure and content of XML documents. It is more powerful than DTD:
| Feature | DTD | XSD |
|---|---|---|
| Written in | Special DTD syntax | XML itself |
| Data types | No built-in types | Rich type system (string, int, date…) |
| Namespaces | Limited support | Full namespace support |
| Extensibility | Not extensible | Can extend and restrict types |
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="age" type="xs:integer"/>
<xs:element name="name" type="xs:string"/>
</xs:schema>
- Well-formed — the document follows all basic XML syntax rules (proper nesting, one root element, quoted attributes, etc.). Any XML parser can read it.
- Valid — the document is well-formed AND conforms to a specific DTD or XSD schema. A validating parser checks both.
All valid XML documents are well-formed, but not all well-formed documents are valid.
When combining XML from different vocabularies, tag name conflicts can occur — both documents may use a <table> tag with different meanings. Namespaces solve this by prefixing element names with a URI.
<root
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns:furn="http://furniture.example.com">
<html:table>
<html:tr><html:td>HTML table cell</html:td></html:tr>
</html:table>
<furn:table>
<furn:width>120cm</furn:width>
</furn:table>
</root>
A default namespace applies to all elements in scope that have no prefix. It is declared with xmlns="..." (no colon prefix).
<!-- All unprefixed elements belong to the XHTML namespace -->
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>Page</title></head>
<body><p>Hello</p></body>
</html>
XPath (XML Path Language) is a query language for navigating and selecting nodes from an XML document. It treats the XML document as a tree of nodes and uses a path syntax similar to file system paths.
<!-- Given this XML: -->
<bookstore>
<book category="fiction">
<title>Dune</title>
<price>15.99</price>
</book>
<book category="tech">
<title>Clean Code</title>
<price>29.99</price>
</book>
</bookstore>
Common XPath expressions:
/bookstore/book— selects all book elements//title— selects all title elements anywhere in the document/bookstore/book[1]— selects the first book/bookstore/book[@category='tech']— selects books with category=”tech”//price[text()>20]— selects prices greater than 20
XSLT (eXtensible Stylesheet Language Transformations) is a language for transforming XML documents into other formats — HTML, plain text, another XML structure, CSV, etc.
<?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>
<h2>Book List</h2>
<xsl:for-each select="bookstore/book">
<p><xsl:value-of select="title"/></p>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
XQuery is a query language for extracting and manipulating data from XML documents and databases. It is to XML what SQL is to relational databases. It uses FLWOR expressions (For, Let, Where, Order by, Return).
for $book in /bookstore/book
where $book/price > 20
order by $book/title
return $book/title
| Feature | DOM Parser | SAX Parser |
|---|---|---|
| Approach | Loads entire document into memory as a tree | Event-driven, reads document sequentially |
| Memory | High — entire tree in RAM | Low — processes one node at a time |
| Navigation | Random access — traverse any node | Forward only — no going back |
| Modification | Can modify the document tree | Read-only |
| Best for | Small/medium documents needing manipulation | Large documents, streaming data |
The browser provides DOMParser to parse an XML string into a DOM document, and XMLSerializer to serialize it back to a string.
const xmlString = `
<bookstore>
<book><title>Dune</title><price>15.99</price></book>
</bookstore>
`;
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(xmlString, "text/xml");
// Access elements
const title = xmlDoc.getElementsByTagName("title")[0].textContent;
console.log(title); // "Dune"
// Check for parse errors
const error = xmlDoc.querySelector("parsererror");
if (error) console.error("XML parse error:", error.textContent);
async function loadXML(url) {
const response = await fetch(url);
const text = await response.text();
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(text, "text/xml");
// Use XPath or DOM methods to query
const books = xmlDoc.querySelectorAll("book");
books.forEach(book => {
console.log(book.querySelector("title").textContent);
});
}
loadXML("/data/books.xml");
- Comments — XML supports comments; JSON does not.
- Metadata via attributes — elements can carry metadata without nesting another object.
- Mature tooling — XSD, XSLT, XPath, XQuery provide a rich ecosystem for validation and transformation.
- Document-centric data — XML is better suited for mixed content (text with embedded markup).
- Namespaces — XML has native namespace support for combining vocabularies.
- Industry standards — SOAP, WSDL, SVG, RSS, and many enterprise formats are XML-based.
XHTML (eXtensible HyperText Markup Language) is HTML reformulated as XML. Because it follows XML rules, it is stricter than HTML:
- All tags must be lowercase.
- All tags must be properly closed — even void elements:
<br />. - All attribute values must be in quotes.
- Attribute names must be lowercase.
- Requires a proper DOCTYPE and root
<html>element with xmlns.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>XHTML Page</title></head>
<body>
<p>All tags closed.</p>
<br />
<img src="photo.jpg" alt="photo" />
</body>
</html>
RSS (Really Simple Syndication) is an XML-based format used to publish frequently updated content such as blog posts, news headlines, and podcasts. Feed readers subscribe to an RSS URL and receive updates automatically.
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
<channel>
<title>My Blog</title>
<link>https://example.com</link>
<description>Latest posts</description>
<item>
<title>First Post</title>
<link>https://example.com/post/1</link>
<pubDate>Mon, 09 Jun 2026 10:00:00 GMT</pubDate>
</item>
</channel>
</rss>
SOAP (Simple Object Access Protocol) is a messaging protocol that uses XML to encode its messages. Every SOAP message is an XML document with a defined envelope structure.
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<!-- optional metadata -->
</soap:Header>
<soap:Body>
<GetUser xmlns="http://api.example.com/">
<UserId>42</UserId>
</GetUser>
</soap:Body>
</soap:Envelope>
XML entities are escape sequences used to represent special characters that would otherwise break XML syntax. The five predefined entities are:
| Entity | Character | Name |
|---|---|---|
& | & | Ampersand |
< | < | Less than |
> | > | Greater than |
' | ‘ | Apostrophe |
" | “ | Quotation mark |
<message>5 < 10 && 10 > 3</message>
<!-- renders as: 5 < 10 && 10 > 3 -->
Even though JSON dominates REST APIs, XML is still widely used in:
- SVG — scalable vector graphics embedded in web pages.
- SOAP web services — enterprise and banking systems.
- RSS/Atom feeds — content syndication.
- Android resources — layouts and configuration in Android apps.
- Maven & Gradle (pom.xml) — Java project build configuration.
- Office documents — DOCX, XLSX, PPTX are ZIP archives of XML files.
- XHTML/MathML — semantic and scientific markup.
XLink (XML Linking Language) defines a standard way to create hyperlinks in XML documents. Unlike HTML’s <a href>, XLink supports simple and extended links, multi-directional links, and links between documents.
<tutorial
xmlns:xlink="http://www.w3.org/1999/xlink"
xlink:type="simple"
xlink:href="chapter1.xml">
Chapter One
</tutorial>
XPointer extends XPath to allow referencing specific parts (fragments) of an XML document — similar to anchor links in HTML but with the full power of XPath expressions.
text() is a node test that selects text node children of an element. An element may have multiple text nodes if it contains child elements interspersed with text.
string() is a function that returns the complete string value of a node — the concatenation of all its descendant text nodes.
<para>Hello <b>World</b> today</para>
<!-- /para/text() → ["Hello ", " today"] (two text nodes) -->
<!-- string(/para) → "Hello World today" (full string) -->
Use document.implementation.createDocument() to create a new XML document and then build the tree using DOM methods.
// Create XML document
const xmlDoc = document.implementation.createDocument("", "bookstore", null);
const root = xmlDoc.documentElement;
// Create and append a book element
const book = xmlDoc.createElement("book");
book.setAttribute("category", "tech");
const title = xmlDoc.createElement("title");
title.textContent = "Clean Code";
book.appendChild(title);
root.appendChild(book);
// Serialize to string
const serializer = new XMLSerializer();
const xmlString = serializer.serializeToString(xmlDoc);
console.log(xmlString);
// <bookstore><book category="tech"><title>Clean Code</title></book></bookstore>