First, I think it's important to make a distinction between two different types of languages:
- A markup language is for writing text documents with extra features, like font styles (bold/italic), hyperlinks, images, lists, or section headers.
- A data serialization language is for representing data objects, which may contain numbers, strings, binary blobs, or other objects. Such a language may be represented as human-readable text for convenience, but the data itself need not conceptually be text.
So, I'll consider these separately.
XML as a data serialization language
XML can be used as a data serialization language, and is widely supported as one. Microsoft's .NET Framework provides built-in support for it, and its documentation provides an example.
<?xml version="1.0" encoding="utf-8"?>
<PurchaseOrder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.cpandl.com">
<ShipTo Name="Teresa Atkinson">
<Line1>1 Main St.</Line1>
<City>AnyTown</City>
<State>WA</State>
<Zip>00000</Zip>
</ShipTo>
<OrderDate>Wednesday, June 27, 2001</OrderDate>
<Items>
<OrderedItem>
<ItemName>Widget S</ItemName>
<Description>Small widget</Description>
<UnitPrice>5.23</UnitPrice>
<Quantity>3</Quantity>
<LineTotal>15.69</LineTotal>
</OrderedItem>
</Items>
<SubTotal>15.69</SubTotal>
<ShipCost>12.51</ShipCost>
<TotalCost>28.2</TotalCost>
</PurchaseOrder>
While this works, the format is pretty verbose. Note that every element name is written twice: For the open tag <X>
and the close tag </X>
. There are three namespace URIs specified, even though in practice most XML-handling code doesn't need to handle element name conflicts.
Also, why is ShipTo.Name
an XML attribute instead of an element? Such a distinction makes sense in a markup language like HTML, which often (but not always) follows the idea that element contents are user-visible while attributes are markup metadata, as in <a href="$URI">$TEXT</a>
. But in a data serialization language, having two ways specifying object fields just seems redundant.
Compare with the equivalent JSON literal:
{
"ShipTo": {
"Name": "Teresa Atkinson",
"Line1": "1 Main St.",
"City": "AnyTown",
"State": "WA",
"Zip": "00000"
},
"OrderDate": "Wednesday, June 27, 2001",
"Items": {
"OrderedItem": {
"ItemName": "Widget S",
"Description": "Small widget",
"UnitPrice": 5.23,
"Quantity": 3,
"LineTotal": 15.69
}
},
"SubTotal": 15.69,
"ShipCost": 12.51,
"TotalCost": 28.2
}
- It's 36% shorter than the XML document.
- There's a syntactic distinction between string literals (with quotation marks), and numeric literals (without quotes). XML is stringly-typed, and thus lacks a convenient way to distinguish the number
123
from the string "123"
, or a null
value from the empty string ""
.
For reasons like these, many developers now prefer to use JSON or YAML for data serialization. After all, they were designed for this purpose. XML was not, as evidenced by the fact that it's named XML (eXtensible Markup Language) instead of something like XDSL (eXtensible Data Serialization Language).
XML as a markup language
There is of course, an XML-based markup language for the Web, named XHTML. So the question here is: Why did HTML5 win out over XHTML?
XHTML's strictness did more harm than good
XHTML requires well-formed XML syntax, which means stricter parsing rules and less tolerance for errors. In theory, this was a feature, in that it allowed parser implementations to be simpler, so that they wouldn't have to work around traditional HTML's infamous "tag soup".
In practice, there were a lot of HTML-generating tools that used simple string concatenation instead of a proper HTML-building library, and didn't pay attention to generating "well-formed" code. Developers generally didn't like seeing their pages fail to render because of a syntax error, and preferred HTML's more forgiving approach. Postel's Law applies.
At least HTML5 made an attempt to standardize error handling, so that "sloppy" HTML code will be handled more consistently.
Backward Compatibility
Closely related to the above, HTML5 was designed to be backward compatible with older versions of HTML, making it easier for existing websites to transition to HTML5 without significant changes. Other than declaring the document as <!DOCTYPE html>
to mark it as HTML5, you might not even have to modify your HTML4 documents at all.
OTOH, XHTML's stricter parsing model made it less compatible with existing HTML documents.
Browser support
Microsoft Internet Explorer simply didn't support XHTML files until version 9 in 2010.
Now, there was a workaround: By using XHTML's Appendix C compatibility guidelines to smooth over the syntactic differences between HTML4 and XHTML, and having User-Agent
-conditional logic to set the Content-Type to text/html
on Internet Explorer but application/xhtml+xml
on better browsers, you could have your XHTML files work on IE.
But, it was simpler to just use text/html
for all browsers, negating any perceived advantage you may have gotten from XHTML.
And, as @user3840170 pointed out in a comment, doing so would have made the page load faster on Firefox, which supported progressive rendering for HTML but not for XHTML.