XML sources
===========

XML capture is available in the development source. The published
``0.1.0.dev0`` package predates this functionality. Configure a local UTF-8
file, explicit namespace-aware selectors and finite limits:

.. code-block:: toml

   schema_version = 1

   [store]
   path = "snapshots"

   [sources.orders]
   kind = "xml"
   path = "orders.xml"
   source_id = "orders"
   schema = { format = "pipewhy.xml-schema", version = 1, root = {namespace = "urn:x", local = "root"}, record = {namespace = "urn:x", local = "row"}, fields = [{id = 1, name = {namespace = "", local = "id"}, location = "attribute", type = "int64", required = true}] }
   limits = { source_bytes = 4096, token_bytes = 512, record_bytes = 512, field_bytes = 128, field_count = 8, depth = 3, batch_records = 1, batch_words = 1000, max_records = 10 }
   worker = { memory_bytes = 536870912, timeout_ms = 15000, frame_bytes = 4000, output_bytes = 10000 }

Supply the lowercase SHA-256 of the exact file bytes as ``--source-version`` to
``pipewhy scan``. A completed snapshot can be reopened, compared and exported
without the file. Malformed or changed input, timeouts and worker failures
produce unavailable observations without retained partial records. Counts are
observed after verification and upstream lineage remains unknown.

The configured root contains direct-child record elements. Selected values are
attributes of a record or simple-text direct children. Names use the namespace
URI and local name; prefixes in the document do not change identity. Local names
in the initial schema use ASCII letters, digits, underscores, dots and hyphens,
and cannot start with a digit, dot or hyphen. Fields have explicit IDs, types
(``text`` or ``int64``) and presence policies. An optional absent field differs
from an empty text field. Null is not inferred or supported in this subset.
Text is preserved without trimming; leading whitespace in an integer is invalid.
Unknown fields, nested elements, duplicate selected children and mixed content
are rejected. Only XML whitespace is allowed between records and fields.

The parser accepts UTF-8 XML 1.0 and normal XML predefined or character
references. It rejects DOCTYPE declarations, custom entities, comments and
processing instructions. Namespace declarations are supported. XML syntax
such as entity spelling and namespace prefixes is interpreted before values are
normalized; it is not retained as a lexical fingerprint. Strict normalization
is the default for decoded values; ``--profile logical-v1`` opts in to logical
normalization.

The limits cover input bytes, parser tokens, record and field bytes, field count,
nesting depth, output batches and total records. A supervised local worker
provides an additional deadline and memory budget; streaming alone does not
limit all native parser allocation. Windows limits job committed memory and
Linux x86_64 limits process virtual address space. These are different measures,
not portable resident-memory limits. The linked Expat version must be at least
2.7.2; unsupported versions and worker platforms fail closed.

The lower-level ``read_xml_batches`` API accepts a local path or a trusted source
opener which must enforce the size limit and verify the digest before successful
exit. It does not implement an S3-compatible connector; remote storage is separate
work.
