Diagram - BPMN XML
Write a supported BPMN model, inspect a detached XML candidate, and accept an undoable import.
#Usage
<script setup lang="ts">
import { shallowRef } from 'vue';
import type { DiagramModel } from '@primeui/vue-diagram';
import { DiagramBpmnXmlExport } from '@primeui/vue-diagram/bpmn-xml';
const props = defineProps<{ model: DiagramModel }>();
const xml = shallowRef<InstanceType<typeof DiagramBpmnXmlExport> | null>(null);
</script>
<template>
<DiagramBpmnXmlExport ref="xml" :value="props.model" filename="process.bpmn">
<button type="button" @click="xml?.export()">Create BPMN XML</button>
<button type="button" @click="xml?.download()">Download BPMN XML</button>
<p v-if="xml?.downloadError" role="alert">{{ xml.downloadError }}</p>
</DiagramBpmnXmlExport>
</template>For live authoring, install createDiagramBpmnModule() in the store and compose Diagram.Root, DiagramBpmnRoot and Diagram.Viewport as shown in BPMN basics. In a small child under that root, useDiagramContext() supplies the current model ref for export and current store and session refs for import. Setup reads use .value; templates unwrap destructured refs.
The store needs createDiagramBpmnModule() for semantic authoring. Import preview and approval are separate from this export operation; use the lifecycle example below.
This skeleton assumes an initialized store with page page. Use First Diagram for model creation, style imports and store disposal.
Import exchange functions and components from @primeui/vue-diagram/bpmn-xml. This optional entry reads and writes the supported descriptive BPMN model and DI geometry. It does not run processes or evaluate expressions.
#Write and reread a small model
Write the single task, then inspect the generated XML, writer identity map and reader notes. Turn owned metadata off to see the presentation-loss report. Reading the output produces a detached immutable model; it does not change the displayed Store. A supported round trip preserves the standard graph and DI within this profile. It is not a byte-identical XML round trip or a promise to preserve every other tool's extensions.
writeDiagramBpmnXml(model, options) returns { ok: true, xml, bytes, identities, diagnostics } or { ok: false, diagnostics }. readDiagramBpmnXml(text, options) returns a detached model, identities and diagnostics on success, with no partial model on failure. DiagramBpmnXmlExport adds export() and browser download() with readonly result and downloadError values on its exposed handle. Its downloaded event reports a download request; the browser owns the final save.
#Preview, accept or reject an import
Paste XML or choose a local file. Preview creates a separate read-only Store for inspection. Accept candidate starts the active Session's import command; this example requires the separate Approve import or Reject import decision. Approval commits one model replacement. Undo restores the previous model; Redo uses the current editing policy. Cancel removes the candidate without committing it. Read-only policy permits inspection but prevents acceptance.
The application constructs DiagramBpmnXmlImportController(store, session) only after the root's Session is available, subscribes to its state, and disposes it when that Session changes or the component is destroyed. preview(text, options) reads immediately; load(loader, options) supplies cancellable, latest-wins transport and prepares the detached candidate in resumable steps. The loading state covers both reading and preparation; input and cancellation can run between steps. accept(), resolve(requestId, accepted), cancel() and dispose() retain Session authority. DiagramBpmnXmlImport is the projected-control alternative with setText, chooseFile, preview, accept, resolve, cancel, state, text and fileError.
| State | Application responsibility |
|---|---|
loading / preview | Show reading/preparation progress or the detached candidate and diagnostics. |
pending-approval | Resolve the exact requestId through the controller; acceptance has not committed. |
pending-store | A controlled Store needs its normal host acknowledgement. Import approval alone is insufficient. |
committed | Read the current Store and keep the root's pageId valid. Accept imports all candidate pages, regardless of the preview page being viewed. |
error / cancelled / stale / disposed | Keep the existing model. Prepare a new candidate when appropriate. |
readDiagramBpmnXml and preview remain synchronous. Use load(async () => text, options) when pasted or already-loaded text needs interruptible preparation. It uses the same parser, mapping, validation, resource limits and immutable result as the synchronous reader. Scheduling adds elapsed time; it does not promise a fixed frame duration or move work into a Worker. No partial candidate is published.
A model revision, another editing preview/proposal, editing-policy change, cancellation or disposal invalidates preparation. Acceptance rechecks ownership and current permissions, including locks and notation validation; a whole-model replacement conservatively requires editing permission for affected owners. Do not set the Store directly to bypass these checks. A successful reader result alone does not authorize acceptance.
The example owns its file input, byte check, FileReader, UTF-8/BOM-marked UTF-16 decoding and error feedback. Changing text cancels the old candidate. The loader observes cancellation and releases callbacks so an old read cannot replace new text. Test native file selection and decoding with the file types and browsers your application supports.
#Use the copied import panel
DiagramBpmnXmlImportUI comes from the optional local @ui/diagram/bpmn-xml
entry. Bind its required importer to the public DiagramBpmnXmlImport adapter.
The panel provides source controls, preview/accept/cancel and diagnostics; it
does not create another controller or bypass the adapter's editing policy.
The example uses ordinary managed acceptance. Use the earlier lifecycle example
when your application requires an approval step or a detached candidate viewport.
The candidate status is preparation feedback, not a rendered preview. You can project an application-owned read-only preview into the panel. Keep its detached Store lifetime and the active root's page ID synchronized with the import result. PrimeOne uses PrimeVue controls; Tailwind supplies the matching HTML controls.
#Writer options
| Option | Default and behavior |
|---|---|
targetNamespace | urn:primeui:diagram:bpmn; an absolute namespace URI used as identity, never fetched. |
extensions | true; validated per-element identity, presentation and inert descriptors. Standard elements still contain the semantic graph. |
descriptors | 'preserve'; retain unresolved inert QName/timer descriptors in owned extensions. 'reject' blocks them. Disabling extensions rejects descriptors that have no standard representation. |
curves | 'flatten'; authored cubic paths become waypoint polylines with approximation diagnostics. 'reject' requires repairing curves first. |
curveError | 0.25 drawing units; allowed 0.01–10, an absolute flattening error bound. |
maxBytes / maxRecords / maxWaypoints | Lower the 8 MiB UTF-8 output, 5,000 node-plus-connector and 4,096 per-edge waypoint ceilings. |
The writer uses authored model geometry. It does not substitute current viewport measurements or interactive derived routes. Collapsed containers use a private expanded projection for internal endpoints while DI retains the expansion flag. Label bounds are portable estimates. Styling, extra labels, ports and ancillary data require owned metadata or produce explicit loss notes.
#Reader options and limits
unsupported defaults to 'reject'. 'omit' allows diagnosed omission of unsupported elements/attributes, but broken required references or invalid ownership still reject. extensions: true restores only validated ancillary owned metadata; standard names, types, endpoints, bounds, scopes and waypoints remain authoritative. extensions: false ignores that metadata with diagnostics.
| Reader ceiling | Default / hard maximum |
|---|---|
maxBytes | 8 MiB of UTF-8 text |
maxDepth / maxTokens | 64 XML levels / 200,000 markup, attribute and entity tokens |
maxText | 8,000,000 decoded UTF-16 text/attribute units |
maxRecords / maxDiagnostics | 5,000 canvas records / 1,000 distinct diagnostics |
The format also bounds pages to 64 and waypoints to 4,096 per edge. Published options may lower their ceilings. Identical notices aggregate with occurrences and the first location; diagnostic saturation rejects. Record count alone does not establish that bytes, expanded IDs, text and tokens fit. A large standard-only import can exceed the output byte ceiling when rewritten with default owned metadata.
The first-party XML parser rejects DTDs, custom/external entities, malformed characters, illegal namespace bindings and duplicate expanded attributes. Predefined/numeric entities, comments, CDATA and namespace shadowing are handled; processing instructions are inert and diagnosed as omitted. No schema, service or external resource is fetched.
#Namespaces and IDs
Element names use expanded namespace names, independent of prefix spelling. Same-document BPMN QName fields accept unprefixed local IDs and valid target-namespace-prefixed references. IDREF fields reject prefixes. A foreign namespace cannot acquire authority by reusing a local ID.
Writer IDs encode [domain, pageId, ownerId, nativeId] injectively. Canvas records, DI, labels, catalogs, event definitions and owner-local IO have distinct domains. Reader allocation handles XML IDs outside native ASCII/length rules without merging or truncating them. Use the returned identities rather than reconstructing IDs. Owned identity hints cannot resurrect undeclared standard records or override standard geometry and semantics.
#Supported interchange and diagnostics
The profile covers the supported task/Call Activity, nested subprocess, loop, event, gateway and flow families, participant lanes, data/catalog/IO associations and Group/Category membership. Each displayed semantic node/flow needs valid DI. Separate nested subprocess planes are rebased through their owner; alternate views of one semantic root reject. Pools need supported rectangular lane geometry; lane-free process-backed participants retain a layout-only body lane without inventing semantic lanes.
Black-box participants, shared processes, standalone process lanes and alternate root DI views are outside the native ownership profile. Executable timer/expression bodies and unresolved standard declarations have no complete native representation; explicit omission may report loss where the graph remains valid. Diagnostics expose severity, code, path, optional id/occurrences, message and representation: standard, extension, approximation, loss or incomplete. Success with completeness warnings does not certify executable correctness.
The interoperability corpus contains downloadable synthetic inputs, supported exchanges and rejected ownership profiles. Its provenance lists the schema and independent modeling tools used to check those files. Use the corpus to compare a candidate with the supported profile; it does not establish compatibility with every BPMN file.
#Interoperability corpus
Download the synthetic corpus provenance and SHA-256 manifest. Supported-profile results apply to these fixtures and documented families, not every file produced by a modeling tool.
| Fixture | Exercised behavior |
|---|---|
| Independent process and unprefixed references | Standalone process, namespaced elements and typed local references. |
| Independent collaboration | Explicit lanes, conventional left participant strips, nested subprocess, boundary event, IO/data association and Category Group. |
| Lane-free collaboration | Process-backed pools with a native body lane but no invented semantic lanes. |
| Nested DI planes | Two nested coordinate frames, boundary attachment, label centers and edge bends. |
| Externally edited process and collaboration | Independent modeler name, geometry and reference edits override stale owned presentation; full supported family fixtures. |
| Externally edited independent collaboration and lane-free collaboration | Independent import, modeling commands and XML save, then native read/write/reopen. |
The following representative inputs reject even with unsupported: 'omit', without changing the active model. They require an ownership or view representation outside the current native model; omitting them would change the graph.
| Rejected fixture | Representation boundary |
|---|---|
| Black-box participant | Native participants each own a process; a participant without processRef does not. |
| Shared process | Two participants cannot share the same native process owner. |
| Standalone process lanes | Native lanes belong to participant pools, not directly to process pages. |
| Alternate DI views | One semantic root has one native view; separate nested subprocess frames are supported, alternate root views are not. |
Small BPMN process · Visual export