DocLang Format#
DocLang is an XML-based semantic markup format designed for LLM/VLM compatibility. It is currently at version 0.7, uses the namespace https://www.doclang.ai/ns/v0 , and supports bidirectional conversion — serving as both an input and output format in Docling alongside Markdown, JSON, HTML, and DocTags.
Its XML vocabulary is purpose-built to encode the full semantics of a DoclingDocument: spatial location data, nested document structure, inline formatting, tables, lists, key-value regions, and cross-page threading for split elements.
Token Vocabulary#
The complete vocabulary is defined in _doclang_utils.py via the DocLangToken enum and organized into categories by DocLangCategory :
| Category | Example tokens |
|---|---|
| Root / Metadata | <doclang>, <head>, <label> |
| Semantic | <heading>, <text>, <caption>, <footnote>, <picture>, <table>, <formula>, <code>, <field_region>, <checkbox> |
| Structural (OTSL tables) | <fcel/>, <ecel/>, <ched/>, <rhed/>, <corn/>, <srow/>, <nl/> |
| Grouping | <list>, <group> |
| Formatting | <bold>, <italic>, <underline>, <strikethrough>, <superscript>, <subscript>, <handwriting> |
| Geometric / Temporal | <location value="N"/>, <layer/>, <hour/>, <minute/> |
| Special | <page_break/> |
| Continuation | <thread thread_id="..."/>, <xref/>, <href/> |
Bounding boxes are encoded as four sequential <location value="N"/> self-closing tokens (x0, y0, x1, y1) normalized to a default resolution of 512 .
Headings support level attributes (1–6); level 1 is emitted as a bare <heading> tag . Lists use class="ordered" or bare <list> for unordered . Code blocks map language labels to GitHub Linguist keys. The root element <doclang version="0.7"> optionally carries an xmlns attribute .
A minimal valid DocLang document looks like:
<doclang>
<heading>DocLang Title</heading>
<text>Hello world</text>
<table>
<fcel/><text>H1</text><fcel/><text>H2</text><nl/>
<fcel/><text>C1</text><fcel/><text>C2</text><nl/>
</table>
</doclang>
Input: Reading DocLang Files#
File extensions: .dclg, .dclg.xml
InputFormat enum: InputFormat.XML_DOCLANG
The entry point is DocLangDocumentBackend in docling/backend/xml/doclang_backend.py. It reads the file as UTF-8 text and delegates to DocLangDocDeserializer.deserialize_str() from docling-core. The deserializer parses the XML, walks the element tree, and populates a DoclingDocument via the builder API. Threading (<thread thread_id="..."/>) is resolved via a registry to merge cross-page continuations .
Usage:
from docling.document_converter import DocumentConverter
from docling.datamodel.base_models import InputFormat
result = DocumentConverter(
allowed_formats=[InputFormat.XML_DOCLANG]
).convert("my_document.dclg")
DocumentConverter.convert_string() is also supported, passing format=InputFormat.XML_DOCLANG .
Output: Exporting to DocLang#
OutputFormat enum: OutputFormat.DOCLANG and OutputFormat.DCLX (archive)
DoclingDocument exposes three export methods in document.py:
| Method | Description |
|---|---|
export_to_doclang(*, add_named_groups=False) | Returns the serialized DocLang XML as a str. When add_named_groups is True, plain GroupItems are serialized as explicit <group name="..."> elements instead of being transparent |
save_as_doclang(filename, *, add_named_groups=False) | Writes XML to a .dclg.xml file |
save_as_doclang_archive(filename, *, add_named_groups=False, ...) | Creates a .dclx OPC archive with images stored under assets/ and page images under pages/. The add_named_groups parameter emits plain GroupItems as <group name="..."> elements so the grouping survives a round trip |
The serializer is DocLangDocSerializer in docling_core/transforms/serializer/doclang.py, configured via DocLangParams. Key parameters include:
add_location(defaultTrue): embed<location>bounding-box tokensadd_page_break(defaultTrue): emit<page_break/>between pagesadd_named_groups(defaultFalse): whenTrue, a plainGroupItemis emitted as a<group>element carrying its name and label, so the grouping survives a round trip. WhenFalse, the group is transparent and only its children are emittedpretty_indentation(default 2 spaces): human-readable formattingimage_mode(defaultPLACEHOLDER): controls how picture data is embeddedinclude_version(defaultTrue): addversion="0.7"to root tag
Serializer / Deserializer Architecture#
The symmetric implementation lives in docling-core:
| Component | File | Key class |
|---|---|---|
| Serializer | docling_core/transforms/serializer/doclang.py | DocLangDocSerializer |
| Deserializer | docling_core/transforms/deserializer/doclang.py | DocLangDocDeserializer |
| Shared vocabulary | docling_core/transforms/serializer/_doclang_utils.py | DocLangToken, DocLangVocabulary |
| Input backend | docling/backend/xml/doclang_backend.py | DocLangDocumentBackend |
The serializer uses specialized sub-serializers for each content type: DocLangTextSerializer, DocLangTableSerializer, DocLangListSerializer, DocLangPictureSerializer, and DocLangKeyValueSerializer .
Roundtrip fidelity is tested in tests/test_backend_doclang.py: exporting a DoclingDocument to DocLang XML and re-importing it must produce identical text content, table grids, and item labels .
Relation to DocTags#
DocLang is distinct from DocTags, which is the XML-like token format emitted by vision models such as SmolDocling. DocTags uses <loc_N> bounding-box tokens and is loaded via DoclingDocument.load_from_doctags(). DocLang is a richer, standards-compliant XML format with explicit namespace, version, OTSL table encoding, and threading support — targeting both human readability and LLM token-level processing.