Skip to main content

Module save

Module save 

Source
Expand description

XML save-context API (upstream xmlsave.c, 2.15.3).

xmlSaveToFd / xmlSaveToFilename / xmlSaveToBuffer / xmlSaveToIO create a save context; xmlSaveDoc / xmlSaveTree serialize into it; xmlSaveFlush / xmlSaveClose / xmlSaveFinish finalize it.

§UPSTREAM-PARITY

xmlSaveCtxt is opaque in the public headers (xmlsave.h); the candidate defines its own internal representation — there is no ABI constraint on its layout. Behavior mirrors xmlsave.c: options XML_SAVE_FORMAT, XML_SAVE_NO_DECL, XML_SAVE_NO_EMPTY and the deprecated escape callbacks. Formatting/decl handling is provided by the tree serializer (serialize_node_opts), which mirrors upstream xmlSaveDoc/ xmlSaveTree/DumpState mechanics.

§Courts

SAVE-* differential cases compare xmlSave* output byte-for-byte with the oracle DSO across option combinations.

§Upstream contract

Mirrors upstream xmlsave.c (+ xmlIO.c output buffers) at libxml2 2.15.3 (SRC-LIBXML2-2.15.0-XMLSAVE-C): xmlSaveToFd / xmlSaveToIO / xmlSaveToFilename / xmlSaveToBuffer, xmlSaveDoc, xmlSaveTree, xmlSaveFlush / xmlSaveFinish / xmlSaveClose, and the deprecated xmlSaveSetEscape / xmlSaveSetAttrEscape hooks.

§Conceptual behavior

A save context wraps an output buffer plus the XML_SAVE_* option mask; xmlSaveDoc/xmlSaveTree delegate to the tree serializer (serialize_node_opts), which mirrors upstream DumpState mechanics (format/indent, XML declaration suppression, empty-element policy).

§Ownership & safety invariants

xmlSaveTo* adopts the output buffer; xmlSaveClose flushes and frees it. The escape/attrEscape callback slots are stored verbatim and never dereferenced by the context (deprecated upstream).

§Historical quirks & epochs

The escape/attrEscape hooks are deprecated since the 2.x era and kept only for source compatibility; the serializer behavior targets the 2.15.3 epoch (e.g. the html-dump single-line epoch E-007 applies to the HTML serializer, and XSLT output relies on these options).

§Deliberate oddities

xmlSaveCtxt is opaque in the public header, so the candidate-internal layout is unconstrained — the deliberate fidelity surface is the behavior, not the struct bytes.

§Proving courts

SAVE-* differential probes (courts/suites/data-abi/*) compare output byte-identical against the oracle DSO; the CLI differential courts (xmllint save paths) and cargo test round-trips cover the options.

§Tempting simplifications that would break parity

Do not drop the deprecated escape callback slots: consumers still set them and observe them firing during serialization. Do not bypass the output-buffer layer (xmlIO.c): flush counts and encoder interaction (R-000151) are observable through xmlSaveFlush/xmlSaveClose.

Structs§

_xmlSaveCtxt
Candidate-internal save context (opaque upstream).

Constants§

XML_SAVE_AS_HTML
Candidate-internal: nokogiri passes SaveOptions::AS_HTML (64) to emit HTML-style output (HTML-void elements stay <br>-style, non-void empty elements get an explicit end tag). Mirrors nokogiri’s flag value, which is 64 (2^6); upstream uses XML_SAVE_AS_HTML = (1<<10).
XML_SAVE_FORMAT
XML_SAVE_FORMAT — format output (newlines + indentation).
XML_SAVE_NO_DECL
XML_SAVE_NO_DECL — don’t emit an XML declaration.
XML_SAVE_NO_EMPTY
XML_SAVE_NO_EMPTY — don’t emit empty tags.

Functions§

xmlSaveClose
int xmlSaveClose(xmlSaveCtxt *ctxt) — flush, close and free the context.
xmlSaveDoc
Serialize doc into the save context’s output buffer.
xmlSaveFileTo
int xmlSaveFileTo(xmlOutputBufferPtr buf, xmlDocPtr cur, const char *encoding) — upstream xmlsave.c delegates to xmlSaveFormatFileTo(buf, cur, encoding, 0).
xmlSaveFinish
xmlParserErrors xmlSaveFinish(xmlSaveCtxt *ctxt) — flush, close, free; returns an xmlParserErrors code (XML_ERR_OK on success).
xmlSaveFlush
int xmlSaveFlush(xmlSaveCtxt *ctxt) — flush the output buffer.
xmlSaveFormatFileTo
int xmlSaveFormatFileTo(xmlOutputBufferPtr buf, xmlDocPtr cur, const char *encoding, int format) — serialize cur into an existing output buffer and close it (upstream xmlsave.c).
xmlSaveSetAttrEscape
int xmlSaveSetAttrEscape(xmlSaveCtxt *ctxt, xmlCharEncodingOutputFunc escape).
xmlSaveSetEscape
int xmlSaveSetEscape(xmlSaveCtxt *ctxt, xmlCharEncodingOutputFunc escape).
xmlSaveSetIndentString
int xmlSaveSetIndentString(xmlSaveCtxt *ctxt, const char *indent).
xmlSaveToBuffer
xmlSaveCtxt *xmlSaveToBuffer(xmlBuffer *buffer, const char *encoding, int options).
xmlSaveToFd
xmlSaveCtxt *xmlSaveToFd(int fd, const char *encoding, int options).
xmlSaveToFilename
xmlSaveCtxt *xmlSaveToFilename(const char *filename, const char *encoding, int options).
xmlSaveToIO
xmlSaveCtxt *xmlSaveToIO(xmlOutputWriteCallback iowrite, xmlOutputCloseCallback ioclose, void *ioctx, const char *encoding, int options).
xmlSaveTree
Serialize a node tree into the save context’s output buffer.