XQuery
XQuery vs XSLT
When to use XQuery and when to use XSLT β a practical decision guide
#XQuery vs XSLT
XQuery and XSLT overlap significantly. Both can query XML, both can produce output, and both use XPath for navigation. This page helps you choose the right tool for each job.
#The Short Answer
|
Task |
Prefer |
|---|---|
|
Transform a document from one format to another |
XSLT |
|
Query a database or document collection |
XQuery |
|
Generate HTML from XML data |
Either (XSLT for template-heavy, XQuery for data-heavy) |
|
Build new XML documents from queries |
XQuery |
|
Apply the same transform to many documents |
XSLT |
|
Ad-hoc data exploration |
XQuery |
|
Identity transform with targeted changes |
XSLT |
|
Join data across multiple documents |
XQuery |
#Paradigm Difference
The fundamental difference is in how you think about the problem:
XSLT is rule-based and declarative. You write template rules that match patterns in the input document. The engine walks the tree and fires rules. You don't control the traversal β you control what happens when a pattern matches.
<!-- XSLT: "When you see a product, render it like this" -->
<xsl:template match="product">
<div class="card">
<h2><xsl:value-of select="name"/></h2>
<p>$<xsl:value-of select="price"/></p>
</div>
</xsl:template>
XQuery is expression-based and procedural (in a functional sense). You write queries that select, filter, transform, and construct. You control the flow explicitly.
(: XQuery: "Select products and build cards from them" :)
for $p in //product
return <div class="card">
<h2>{ $p/name/text() }</h2>
<p>${ $p/price/text() }</p>
</div>
For C# developers: XSLT resembles event handlers β you register what should happen when something occurs. XQuery resembles LINQ β you write the query that produces the result.
#Strengths Comparison
#Where XSLT Excels
Document-centric transforms. XSLT's template matching handles document-centric transforms naturally. This applies when you transform one XML format to another and the output structure closely mirrors the input structure:
<!-- Copy everything, change just the price format -->
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="price">
<price formatted="true">
$<xsl:value-of select="format-number(., '#,##0.00')"/>
</price>
</xsl:template>
In XQuery, you must reconstruct the entire document tree to change one element.
Multiple output documents. XSLT's xsl:result-document generates many output files from a single input. This suits static site generation, batch PDF creation, and splitting large documents.
Reusable template libraries. XSLT's import/include mechanism with priority-based override is well-suited to building theme systems and customizable document pipelines.
Streaming. XSLT 3.0 supports streaming transformations for very large documents that don't fit in memory.
#Where XQuery Excels
Database queries. XQuery was designed as a query language for XML databases. It's the SQL of the XML world:
for $order in collection("orders")//order
where $order/@date > xs:date("2026-01-01")
and $order/total > 1000
order by $order/total descending
return $order
Cross-document joins. XQuery naturally joins data from multiple sources:
for $order in doc("orders.xml")//order
let $customer := doc("customers.xml")//customer[@id = $order/@customer-id]
return <summary>
<order-id>{ string($order/@id) }</order-id>
<customer>{ $customer/name/text() }</customer>
<total>{ $order/total/text() }</total>
</summary>
Ad-hoc analysis. XQuery expressions can be written interactively (REPL-style) for exploring data:
(: Quick analysis β no boilerplate needed :)
let $orders := doc("orders.xml")//order
return map {
"count": count($orders),
"total": sum($orders/total),
"avg": avg($orders/total),
"top-customer": (
for $cid in distinct-values($orders/@customer-id)
let $customer-total := sum($orders[@customer-id = $cid]/total)
order by $customer-total descending
return $cid
)[1]
}
Constructing new documents. XQuery's constructor syntax is more natural for building complex XML from scratch:
<report generated="{ current-dateTime() }">
{
for $category in distinct-values(//product/@category)
let $products := //product[@category = $category]
return <section name="{ $category }">
<stats count="{ count($products) }" avg-price="{ avg($products/price) }"/>
{ $products }
</section>
}
</report>
#They Share XPath
Both languages use XPath 3.1/4.0 for navigation and expression evaluation. All XPath functions, operators, and data types work identically in both. This means:
-
Knowledge of XPath transfers directly to both languages.
-
You can use the same navigation expressions in XSLT match patterns and XQuery FLWOR clauses.
-
Function libraries (string, numeric, date, sequence) are identical.
#Using Them Together
In practice, you often use both:
-
XQuery to select and prepare data from a database or document collection
-
XSLT to transform the prepared data into the final output format
Example pipeline:
XML Database β XQuery (select + join + aggregate) β intermediate XML β XSLT (β HTML)
This is exactly what PhoenixmlDb enables β XQuery for database operations, XSLT for rendering.
#Decision Framework
Ask these questions:
1. Are you transforming a document or querying data?
-
Transforming β XSLT
-
Querying β XQuery
2. Does the output closely mirror the input structure?
-
Yes (most nodes copied, few changes) β XSLT (identity transform pattern)
-
No (different structure, aggregation, joins) β XQuery
3. Do you need multiple output files?
-
Yes β XSLT (
xsl:result-document) -
No β Either
4. Is the input from a database or collection?
-
Database/collection β XQuery
-
Single document or known set β Either
5. Do you need reusable, overridable templates?
-
Yes β XSLT (import/include with priority override)
-
No β Either
6. Are you doing ad-hoc exploration?
-
Yes β XQuery (less boilerplate)
-
No β Depends on the task
#The .NET Developer's Perspective
-
XQuery feels more natural initially. It is expression-based like LINQ, with explicit control flow.
-
XSLT requires a paradigm shift to declarative, rule-based thinking. Once it clicks, it handles document-centric work well.
-
Learn XPath first. It is the foundation for both languages.
-
Start with XQuery for data queries and exploration.
-
Move to XSLT when you need document transformation, multi-output generation, or template-based rendering.
Both are valuable tools. The best .NET developers working with XML use both, choosing the right one for each task.
For C# developers: XQuery feels closer to LINQ and is usually the easier starting point.