$ lexprog.com

// notes from an old coder -- php, databases, and the occasional rant

[May 02, 2026] PostgreSQL

PostgreSQL XML Data Handling

PostgreSQL XML Data Handling

────────────────────────────────────────────────────────

PostgreSQL XML Data Handling

Tip: Store XML

CREATE TABLE documents (id SERIAL, content XML);
INSERT INTO documents VALUES (1, '<root><item>value</item></root>');

Gotcha: XPath Query

SELECT xpath('/root/item/text()', content) FROM documents;

Tip: XML to JSON

SELECT json_build_object('data', content::text)::json FROM documents;

Gotcha: XML Validation

PostgreSQL validates XML on insert. Invalid XML is rejected.

Tip: xmlelement() Function

SELECT xmlelement(name item, xmlattributes(id AS id), title) FROM posts;

Gotcha: XML Performance

XML operations are slower than JSON. Prefer JSONB for new projects.

Tip: EXPLAIN (ANALYZE, BUFFERS) Is Your Best Friend

For query debugging, always use EXPLAIN (ANALYZE, BUFFERS) instead of plain EXPLAIN. The BUFFERS option shows hit/miss rates for every node, revealing whether your indexes are actually in memory.

Tip: Partial Indexes Are Underutilized

CREATE INDEX ON orders (status) WHERE status = 'pending' creates a tiny index that covers only the rows your query needs. It's faster to scan and cheaper to maintain than a full-column index.

Gotcha: NULL Sorting Is Non-Obvious

By default, NULLs sort AFTER non-null values in ascending order. ORDER BY col DESC puts NULLs FIRST. Use NULLS LAST or NULLS FIRST to be explicit.

Senior Insight

PostgreSQL's XML handling functions are rarely needed, but when they are, they're irreplaceable. I've used xmlelement(), xmlagg(), and xmlforest() for generating XML feeds directly from database queries. For most web applications, generating XML in application code is cleaner. But for high-volume XML export pipelines, doing it in SQL avoids the serialization overhead of fetching rows to the application layer.

Source: pganalyze Blog (https://pganalyze.com/blog), PostgreSQL Docs (https://www.postgresql.org/docs/current/), Crunchy Data Blog (https://www.crunchydata.com/blog)

────────────────────────────────────────────────────────
<-- back to posts