Skip to content
getnextpdf.com

Pro edition

Form — Deep Reference

This page is the deep reference for the Pro Form module. It covers AcroForm value extraction, XFDF read and write, data binding, and XFA data extraction. The module consumes NextPDF\Form\FormField values produced by the Core form reader and adds serialization, parsing, and binding on top of them. XFA support is data-oriented: the parser structures the template and datasets packets. It does not execute XFA calculation scripts or render dynamic XFA layouts.

This capability ships in NextPDF Pro (nextpdf/pro) and activates with a Pro-tier license envelope. A deployment without that entitlement does not load the capability’s classes. Compare editions and get a license.

No per-feature license flag exists. This is a Pro-edition capability.

SymbolParametersDefault behaviorReturnsThrows or fails withNotes
FormDataExtractor::extractlist<FormField> $fieldsReads each field’s name and valueXfdfDataIncludes fields whose value is empty.
FormDataExtractor::toArraylist<FormField> $fieldsBuilds a name-to-value string maparray<string, string>A later duplicate name overwrites an earlier one.
FormDataExtractor::toXfdflist<FormField> $fields, ?string $pdfHref = nullDelegates to XfdfWriter::fromFieldsstring (XFDF XML)Convenience path for one-call export.
FormDataExtractor::extractNonEmptylist<FormField> $fieldsSkips fields whose value is the empty stringXfdfData
FormDataExtractor::getEmptyFieldNameslist<FormField> $fieldsLists names of fields with no value setlist<string>Complement of extractNonEmpty.
XfdfWriter::fromFieldslist<FormField> $fields, ?string $pdfHref = nullCollects name-to-value pairs, delegates to fromArraystring (XFDF XML)
XfdfWriter::fromArrayarray<string, string> $data, ?string $pdfHref = nullWraps the map in XfdfData, delegatesstring (XFDF XML)
XfdfWriter::fromXfdfDataXfdfData $data, ?string $pdfHref = nullSerializes to XFDF; dot-notation names nest as hierarchical <field> elementsstring (XFDF XML)Strips XML-1.0-illegal control characters; see the behavior contract.
XfdfParser::parsestring $xfdfXmlLoads the XML XXE-safe and flattens fields to dot notationXfdfDataInvalidArgumentException10 MiB input ceiling; accepts namespaced and non-namespaced roots.
XfdfParser::parseFilestring $filePathResolves the path, reads the file, delegates to parseXfdfDataInvalidArgumentExceptionMissing, non-file, or unreadable paths raise.
XfaParser::parsestring $pdfDataMarker check, XML extraction, packet parseXfaFormDataInvalidArgumentException, XfaParseExceptionNo /XFA marker returns an empty result, not an error.
XfaParser::hasXfastring $pdfDataScans the bytes for the /XFA markerboolByte-marker scan; any occurrence of the token matches.
XfaParser::extractXfaXmlstring $pdfDataStream scan for XFA markers, then direct <xdp:xdp> searchstring (XFA XML or '')RuntimeException (declared)Scans at most the first 50 MiB of the input.
XfaParser::parseXmlstring $xmlExtracts template and datasets packets, parses <field> elementsXfaFormDataXfaParseException10 MiB XML ceiling, enforced before DOM load.
FormDataBinder::bindlist<FormField> $fields, XfdfData $dataCreates new FormField instances with bound valuesFormDataBindResultOriginals are never modified; check boxes normalize to Yes/Off.
FormDataBinder::fromXfdflist<FormField> $fields, string $xfdfXmlParses the XFDF, then bindsFormDataBindResultInvalidArgumentExceptionFailure modes are those of XfdfParser::parse.
FormDataBinder::fromArraylist<FormField> $fields, array<string, string> $dataWraps the map in XfdfData, then bindsFormDataBindResult
FormDataBindResultisFullyBound, hasNoUnmatchedKeys, boundCount, fieldCount; readonly fields, boundFieldNames, unmatchedDataKeys, unboundFieldNamesImmutable bind diagnosticsper methodisFullyBound requires zero unmatched keys and zero unbound fields.
XfdfDatahasField, getValue, count, isEmpty, getFieldNames, withField, withoutField, merge; readonly fieldsImmutable name-to-value containerper methodwith* and merge return new instances; merge prefers the argument’s values.
XfaFormDatagetField, hasField, count, fieldNames; readonly fields, templateXml, datasetsXmlImmutable XFA parse resultper methodCarries raw template and datasets packet XML for round-tripping.
XfaFormFieldreadonly name, type, value, required, caption, optionsImmutable single-field recordtype is one of text, numeric, date, choice, button, signature.
XfaPacketenum cases Template, Datasets, Config, LocaleSet, ConnectionSet, Form; xmlNamespace()String-backed packet enumerationstring from xmlNamespace()Namespace URIs follow the XFA Specification 3.3.
public static function extract(array $fields): XfdfData
public static function toArray(array $fields): array
public static function toXfdf(array $fields, ?string $pdfHref = null): string
public static function extractNonEmpty(array $fields): XfdfData
public static function getEmptyFieldNames(array $fields): array
public static function fromFields(array $fields, ?string $pdfHref = null): string
public static function fromArray(array $data, ?string $pdfHref = null): string
public static function fromXfdfData(XfdfData $data, ?string $pdfHref = null): string
public static function parse(string $xfdfXml): XfdfData
public static function parseFile(string $filePath): XfdfData
public function parse(string $pdfData): XfaFormData
public function hasXfa(string $pdfData): bool
public function extractXfaXml(string $pdfData): string
public function parseXml(string $xml): XfaFormData
public static function bind(array $fields, XfdfData $data): FormDataBindResult
public static function fromXfdf(array $fields, string $xfdfXml): FormDataBindResult
public static function fromArray(array $fields, array $data): FormDataBindResult
  • NextPDF\Pro\Form\Exception\XfaParseException extends RuntimeException — the XFA payload cannot be parsed into an XfaFormData. The subclassing is deliberate: existing catch (RuntimeException $e) call sites keep working.
  • SPL InvalidArgumentException — empty, oversized, malformed, or non-XFDF input to XfdfParser; empty PDF input to XfaParser::parse; unreadable paths in XfdfParser::parseFile.

AcroForm extraction. FormDataExtractor walks the field list you pass and reads each field’s name and value. extract returns an XfdfData; toArray returns a plain name-to-value string map. extractNonEmpty drops fields whose value is the empty string; getEmptyFieldNames returns the complementary name list. Extraction never mutates the input fields.

XFDF write. XfdfWriter produces a document conforming to the ISO 19444-1:2019 structure. Output starts with the XFDF XML declaration and an xfdf root in the Adobe XFDF namespace (http://ns.adobe.com/xfdf/) with xml:space="preserve". A non-null pdfHref emits an <f href="..."/> reference back to the source PDF. Dot-notation field names (for example address.city) nest into a hierarchical <field> element tree. Values and attributes escape the five XML metacharacters. Field names, values, and the pdfHref are additionally normalized for well-formedness: the C0 control characters that XML 1.0 forbids are stripped, while TAB, LF, and CR are preserved. This normalization is lossy by design, so the writer always emits well-formed, re-parseable XFDF regardless of caller-supplied bytes.

XFDF read. XfdfParser accepts both namespaced and non-namespaced xfdf roots and matches the root name case-insensitively, because some producers emit an uppercase root element. Hierarchical <field> trees flatten back to dot-notation names, so write and read round-trip. All XML loading disables network access and external-entity resolution. parseFile adds path resolution and readability checks in front of the same parse.

Data binding. FormDataBinder::bind matches data keys against field names. Because FormField is immutable, binding creates new instances with updated values; the originals are never modified. The result reports three diagnostic sets: bound field names, data keys with no matching field, and fields that received no data. Check-box values normalize to the on/off state model of ISO 32000-2:2020, 12.7.5.2.3: case-insensitive yes, true, 1, and on map to Yes; every other value maps to Off.

XFA data extraction. XfaParser::parse accepts raw PDF bytes. It first scans for the /XFA marker; absent the marker it returns an empty XfaFormData. Extraction then tries two strategies: a scan of streamendstream blocks for XFA XML indicators, then a direct search for a <xdp:xdp> document. A single xdp:xdp fragment is returned as-is; multiple fragments are concatenated into a synthesized xdp:xdp envelope. parseXml extracts the template and datasets packets and parses each template <field> element into an XfaFormField: the name attribute is required, the type derives from the field’s UI child element, the required flag derives from a validate element with nullTest set to error, and choice options come from items children.

XFA support is data-oriented. The parser structures the template and datasets packets. It does not execute XFA calculation scripts, render dynamic XFA layouts, or round-trip every packet type. Validate the parser against your specific document set before relying on it.

  • XfdfParser::parse('') throws InvalidArgumentException. Input above 10 MiB throws InvalidArgumentException naming the ceiling.
  • Malformed XML throws InvalidArgumentException carrying the collected libxml messages. A well-formed document whose root is not xfdf throws and names the actual root element.
  • An XFDF document without a <fields> element parses to an empty XfdfData; that is not an error.
  • Field elements without a name attribute are skipped in both XFDF and XFA parsing. An XFDF field without a <value> child contributes no entry.
  • XfaParser::parse('') throws InvalidArgumentException. A PDF without the /XFA marker, or one whose XFA XML cannot be located, returns an empty XfaFormData instead of throwing.
  • hasXfa is a byte-marker scan: any /XFA token in the file matches, including one in an unused object. The subsequent extraction step decides whether usable XML exists.
  • XFA extraction examines at most the first 50 MiB of the PDF byte string; content beyond that bound is not scanned.
  • XFA XML above 10 MiB throws XfaParseException before any DOM tree is materialized. Malformed XFA XML throws XfaParseException with the libxml messages.
  • Check-box normalization never passes unrecognized values through; anything outside the accepted on-forms maps to Off.
  • The writer’s control-character stripping is lossy: XML-1.0-illegal C0 bytes in names, values, or the pdfHref are dropped so the output stays well-formed. TAB, LF, and CR survive.
  • All XML parsing disables external-entity resolution and network access (XXE-safe).
  • This module performs no cryptographic operations; FIPS mode does not change its behavior.
BehaviorReferenceStatus
Interactive form / field dictionary modelISO 32000-2:2020, 12.7Aligned (product-grounded)
Check-box on/off state normalization (Yes/Off)ISO 32000-2:2020, 12.7.5.2.3Aligned; clause cited in this page’s citation record
XFDF data-exchange structureISO 19444-1:2019Aligned (product-grounded)
XFA packet names and namespace URIsXFA Specification 3.3Aligned (product-grounded)

These statements describe capability against the referenced documents.

  • Every entry point except XfaParser is static. XfaParser is instantiable and stateless; one instance is safe to reuse across documents.
  • The intended round-trip is: Core form reader produces FormField values; FormDataExtractor or XfdfWriter serializes them; XfdfParser reads the data back; FormDataBinder applies it to a field list. Hierarchical names survive the round-trip through dot notation.
  • Use the FormDataBindResult diagnostics (isFullyBound, unmatchedDataKeys, unboundFieldNames) to detect drift between an XFDF data file and a revised PDF template before accepting a fill.
  • XfdfData is a value object: withField, withoutField, and merge return new instances. On key collisions, merge prefers the argument’s values.
  • XfaFormData retains the raw template and datasets packet XML (templateXml, datasetsXml) so you can post-process packets the field model does not cover.
  • This module does not parse AcroForm dictionaries out of PDF bytes itself; it consumes fields produced by the Core form reader. Only XfaParser operates on raw PDF content.

This page documents externally observable behavior and the supported public API surface only. Internal namespace paths, helper classes, mechanism tables, runbook filenames, and ticket prefixes are out of scope.