Skip to content

feat(db): serialization parameters on GET /api/db/resource#48

Open
joewiz wants to merge 1 commit into
eXist-db:developfrom
joewiz:feat/db-resource-serialization
Open

feat(db): serialization parameters on GET /api/db/resource#48
joewiz wants to merge 1 commit into
eXist-db:developfrom
joewiz:feat/db-resource-serialization

Conversation

@joewiz

@joewiz joewiz commented Jun 6, 2026

Copy link
Copy Markdown
Member

[This PR was co-authored with Claude Code. -Joe]

From the existdb-oxygen-plugin (oxex) serialization tasking. GET /api/db/resource did a bare serialize($doc) with no caller control, so XML output was dictated entirely by the instance's conf.xml serializer defaults.

What this adds

Optional W3C serialization parameters on GET /api/db/resource, passed through to serialize() via an output:serialization-parameters element built from only the keys the caller supplies:

  • method (xml | xhtml | html5 | text | json | adaptive)
  • indent (yes/no, tolerates true/false)
  • omit-xml-declaration (yes/no, tolerates true/false)
  • encoding, media-type, item-separator

Backward compatible: with no serialization params, the handler still does a bare serialize($doc) — byte-for-byte identical to before (the conf.xml defaults). Binary resources are unaffected.

expand-xincludes is intentionally NOT included — and here's the important part

The tasking's centerpiece was expand-xincludes=no on read, so an open→edit→save round-trip wouldn't silently destroy <xi:include>. That turns out to be unachievable in eXist 7.0.0-beta3. I verified every mechanism expands the include:

  • fn:serialize($doc, map{"expand-xincludes":"no"}) and the eXist-namespaced map key → expand
  • util:declare-option("exist:serialize","expand-xincludes=no") + serialize($doc, <output:serialization-parameters/>)eXide's exact pattern → expands
  • REST streaming GET default, ?_xinclude=no, ?_expand-xincludes=no → expand (RESTServer hard-codes EXPAND_XINCLUDES=yes; RESTServerParameter has no override)
  • util:serialize (the eXist-6 node→string function that honored eXist serializer options) was removed in eXist 7 with no replacement

Only static declare option exist:serialize "expand-xincludes=no" on a query result works — unusable for a per-request string embedded in a JSON envelope.

Advertising expand-xincludes=no while silently expanding would hand clients a false guarantee and risk destroying includes on save, so it's omitted pending an eXist-core fix.

Two things for follow-up (tracked separately):

  1. An eXist-core change to make expand-xincludes controllable for node→string serialization.
  2. eXide on eXist 7 has the same latent data-loss bug — its "Open with Expand XIncludes off" doesn't actually work; verified it expands end-to-end. Not unique to this API; worth tracking on the eXide side.

Verification

  • db.cy.js: 5 new tests (default = backward-compat, indent yes/no, true/false tolerance, omit-xml-declaration, binary-unaffected). Full db.cy.js green.
  • Manual: indent=yes pretty-prints, indent=no compact, omit-xml-declaration=no includes the declaration, no-params output identical to pre-change.

api.json documents the new params and the expand-xincludes caveat.

From the existdb-oxygen-plugin (oxex) tasking. GET /api/db/resource did
a bare serialize($doc) with no caller control, so XML output was dictated
entirely by the instance conf.xml serializer defaults. Add optional W3C
serialization parameters — method, indent, omit-xml-declaration,
encoding, media-type, item-separator — passed through to serialize() via
an output:serialization-parameters element built from only the keys the
caller supplied.

Backward compatible: with no serialization params the handler still does
a bare serialize($doc), so output is byte-for-byte identical to before
(the conf.xml defaults). Binary resources are unaffected. Boolean params
accept yes/no (the cursor query-results vocabulary) and tolerate
true/false.

expand-xincludes deliberately NOT included. The tasking's centerpiece —
expand-xincludes=no for safe open/edit/save round-trips — turns out to be
unachievable in eXist 7.0.0-beta3: fn:serialize always expands,
util:serialize was removed, util:declare-option+serialize(element)
(eXide's pattern) expands anyway, and the REST layer hard-codes
expand-xincludes=yes. Advertising the param while silently expanding
would give clients a false guarantee and risk destroying <xi:include> on
save, so it is omitted pending an eXist-core fix. Full write-up:
the finding doc accompanying this work. (Same latent data-loss exposure
affects eXide on eXist 7 — its Open-with-expand-xincludes-off does not
actually work either.)

api.json documents the new query params and the expand-xincludes caveat.
Cypress: 5 new tests — default (backward compat), indent yes/no,
true/false tolerance, omit-xml-declaration, and binary-unaffected.

Refs oxex serialization tasking (2026-06-06).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant