Custom XML data parts —
customXml/item{N}.xml+customXml/itemProps{N}.xml(§17.5.2 + §22.4).
Module docxCustomXml | Source packages/front/office/ooxml/src/docx/customXml.js | Deps ooxmlErrors, xml, ooxmlShared | Worker-safe yes
A docx can carry arbitrary user XML and bind SDTs to XPaths through a storeItemID. Each data store lives in two parts: item{N}.xml (opaque user XML) and itemProps{N}.xml (<ds:datastoreItem ds:itemID="{GUID}"> + schemaRefs).
Resolve
const cx = runtime.resolve('docxCustomXml');
// Returns: { parseProps, renderProps, propsBytes,
// generateStoreItemID,
// DS_NS,
// REL_TYPE_CUSTOM_XML, REL_TYPE_CUSTOM_XML_PROPS,
// CT_CUSTOM_XML_PROPS }
API
| Method | Signature | Returns |
|---|---|---|
parseProps |
(text|bytes) => { storeItemID, schemaRefs? } |
Typed props. |
renderProps |
(props) => string |
<ds:datastoreItem> XML. |
propsBytes |
(props) => Uint8Array |
UTF-8 bytes. |
generateStoreItemID |
() => '{GUID}' |
Brace-wrapped RFC 4122 v4 GUID from crypto.getRandomValues; throws docx/no-random-source without it. |
DS_NS, REL_TYPE_CUSTOM_XML, REL_TYPE_CUSTOM_XML_PROPS, CT_CUSTOM_XML_PROPS |
string | OPC bindings. |
Model
{
storeItemID: '{0EBA2C1A-…}', // GUID, the lookup key of SDT.dataBinding
schemaRefs?: [string] // optional schema URIs
}
Relationship chain:
/word/document.xml
└─ customXml rel → /customXml/item1.xml (opaque user XML)
/customXml/item1.xml
└─ customXmlProps rel → /customXml/itemProps1.xml (typed props)
Examples
Attach a data store
const cx = runtime.resolve('docxCustomXml');
const id = cx.generateStoreItemID(); // '{A1B2C3D4-…}'
const userXml = '<root><name>Alice</name></root>';
const props = { storeItemID: id, schemaRefs: ['urn:my-schema'] };
// Place the parts and their relationships by hand:
opc.setPart(pkg, '/customXml/item1.xml', opc.stringToBytes(userXml));
opc.setPart(pkg, '/customXml/itemProps1.xml',
cx.propsBytes(props), cx.CT_CUSTOM_XML_PROPS);
opc.setRels(pkg, '/word/document.xml', [
{ Id: 'rIdCx1', Type: cx.REL_TYPE_CUSTOM_XML, Target: '../customXml/item1.xml' }
]);
opc.setRels(pkg, '/customXml/item1.xml', [
{ Id: 'rIdCxP1', Type: cx.REL_TYPE_CUSTOM_XML_PROPS,
Target: 'itemProps1.xml' }
]);
Read
const props = cx.parseProps(pkg.parts['/customXml/itemProps1.xml']);
// → { storeItemID: '{…}', schemaRefs: ['urn:…'] }
Notes
generateStoreItemIDusescrypto.getRandomValues; without it,generateStoreItemIDthrowsdocx/no-random-source(RenderError) — passstoreItemIDexplicitly. The source is read fromglobalThis.cryptoat each call.storeItemIDmust be unique within the package and match thedataBinding.storeItemIDof every SDT bound to it.- The item part is opaque — the module never parses its content (arbitrary user-defined XML).
- Word also accepts
itemPropswithoutschemaRefs; the array is then omitted from the parsed object. - A props root other than
<ds:datastoreItem>raisesParseError('docx/customxml-bad-root').
See also
- docx — orchestrator (reads/writes the customXml parts).
- docx-structure — SDTs with
dataBinding.