Skip to main content

Module validation

Module validation 

Source
Expand description

DTD validation (§27, §85 Phase 6).

DTD validation against element/attribute declarations:

  1. Element content model validation — does the element’s child sequence match its declared content model?
  2. Attribute value validation — does each attribute’s value conform to its declared type (CDATA, ID, IDREF, IDREFS, ENTITY, ENTITIES, NMTOKEN, NMTOKENS, ENUMERATION, NOTATION)?
  3. ID/IDREF consistency — are all ID values unique? Does each IDREF reference a valid ID?
  4. Required attributes — are all REQUIRED attributes present?
  5. NOTATION validation — are NOTATION attributes referencing declared notations?
  6. Well-formedness constraints — additional validity constraints

§UPSTREAM-PARITY

This module follows upstream libxml2 valid.c implementation. The validation context (xmlValidCtxt) accumulates ID/IDREF tables across the document and checks consistency in xmlValidateDocumentFinal.

§Phase 6 status

Complete — all core DTD validation functions are implemented. Edge-case behavior for degenerate DTDs matches upstream.

§Upstream contract

Mirrors upstream valid.c (SRC-LIBXML2-2.15.0-VALID-C, oracle tree oracle/historical/src/libxml2-2.15.0/valid.c): xmlValidateDocument, xmlValidateDtd, xmlValidCtxt ID/IDREF tables, xmlValidateElement, xmlValidateAttributeDecl and the content-model validation walks.

§Conceptual behavior

DTD validation against element/attribute declarations: content-model matching, attribute value types (CDATA, ID, IDREF(S), ENTITY(IES), NMTOKEN(S), ENUMERATION, NOTATION), ID/IDREF consistency, REQUIRED attributes, NOTATION references and well-formedness constraints. The xmlValidCtxt accumulates ID/IDREF tables across the document and checks consistency in xmlValidateDocumentFinal.

§Ownership & safety invariants

Ownership: the validation context owns its ID/IDREF table storage and error output; the document and declarations are borrowed. SAFETY: the recursive validation walks are depth-bounded (VALID_CTXT_DEPTH_MAX = 256) to avoid stack exhaustion on degenerate DTDs.

§Historical quirks & epochs

E-005: –valid on an invalid document exits 3 from 2.13.0 (was 4); E-006: –valid with no DTD exits 0 from 2.15.0 (was 3) — the no-DTD-found failure stopped being exit-worthy. Parse-time ID/IDREF registration (xmlIsID/xmlAddID) was aligned with upstream in 11.1-N (R-000164); the _xmlElement mirror is 104 bytes (R-000139).

§Deliberate oddities

Deliberate oddities: element-decl type_ carries XML_ELEMENT_DECL while etype holds the element type (upstream field split); ATTLISTs for undeclared elements create UNDEFINED placeholders not linked into the DTD children (xmlGetDtdElementDesc semantics).

§Proving courts

DTD, RELAXNG and XSD court families; TREE-001 (ID/IDREF registration, atype = XML_ATTRIBUTE_ID), CLI-XMLLINT valid cases (exit codes 3/0 per E-005/E-006) and cargo test --lib.

§Tempting simplifications that would break parity

A tempting simplification is skipping parse-time ID registration and resolving IDs lazily at validation time — it would break doc->ids fingerprints and xmlIsID semantics (R-000164). Do not unbounded the recursion: VALID_CTXT_DEPTH_MAX mirrors the hardened oracle (SD-002).

Structs§

ContentModelExec
Runtime exec state for one open element’s content model.
ContentModelNfa
Incremental content-model matcher stored in _xmlElement.cont_model.

Functions§

add_id
Upstream xmlAddID(ctxt, doc, value, attr) — returns the xmlID or NULL. Reports “ID %s already defined” through the validation context on duplicates and a memory error on OOM.
add_id_safe
Upstream xmlAddIDSafe(attr, value) (2.13+): add an ID without a validation context. Returns 1 on success, 0 if the ID already exists, -1 on OOM.
add_ref
Upstream xmlAddRef(ctxt, doc, value, attr) — registers an IDREF. Returns the xmlRef or NULL.
free_content_model_nfa
Free a compiled content-model NFA (called from xmlFreeElement).
free_id_table
Upstream xmlFreeIDTable(table).
free_ref_table
Upstream xmlFreeRefTable(table).
free_valid_ctxt
Free a validation context.
get_dtd_attr_desc
Upstream xmlGetDtdAttrDesc(dtd, elem, name) — attribute declaration lookup splitting the attribute QName into (local, prefix).
get_dtd_element_desc
Upstream xmlGetDtdElementDesc(dtd, name) — plain element declaration lookup with QName splitting.
get_dtd_notation_desc
Upstream xmlGetDtdNotationDesc(dtd, name).
get_dtd_qattr_desc
Upstream xmlGetDtdQAttrDesc(dtd, elem, name, prefix) — the attribute declaration table is keyed by (name, prefix, elem).
get_dtd_qelement_desc
Upstream xmlGetDtdQElementDesc(dtd, name, prefix).
get_id
Upstream xmlGetID(doc, ID): returns the attribute holding the ID, or the document pointer itself when operating on a stream (attribute node no longer exists).
get_refs
Upstream xmlGetRefs(doc, ID): returns the list of references for an ID.
is_empty_element
Check if an element is declared as EMPTY.
is_id
Upstream xmlIsID(doc, elem, attr): is this attribute an ID? Handles the HTML special cases (id attribute; name attribute on <a>) and the DTD declaration lookup, plus the xml:id namespace convention.
is_mixed_element
Check if an element has a mixed content model.
is_ref
Upstream xmlIsRef(doc, elem, attr): is this attribute an IDREF?
new_valid_ctxt
Create a new validation context.
remove_id
Upstream xmlRemoveID(doc, attr) — removes the attribute’s ID entry. Returns 0 on success, -1 otherwise.
remove_ref
Upstream xmlRemoveRef(doc, attr) — removes the attribute’s IDREF entry. Returns 0 on success, -1 otherwise.
set_valid_errors
Set error and warning callbacks on a validation context.
split_qname4
Split a QName at the FIRST ‘:’ (upstream tree.c xmlSplitQName4): prefix receives a duplicated prefix (or NULL) and the local name (a pointer into the original string) is returned.
validate_attribute_decl
Validate an attribute’s value against its declaration.
validate_attribute_value
Validate an attribute value against its declared type.
validate_build_content_model
Upstream xmlValidBuildContentModel(ctxt, elem): compile the element’s content tree into a content-model NFA cached in elem->contModel. Returns 1 on success, 0 on failure.
validate_content
Validate the content of an element node against its content model.
validate_document
Validate an entire document against its DTD.
validate_document_final
Final validation: check that all IDREFs resolve to existing IDs.
validate_dtd
Validate a DTD’s declarations (element/attribute declarations).
validate_dtd_final
Final DTD validation — checks ID/IDREF consistency.
validate_element
Validate a single element node against its DTD element and attribute declarations.
validate_element_decl
Upstream xmlValidateElementDecl(ctxt, doc, elem): verifies the declaration is not duplicated and that MIXED content models do not list the same element twice.
validate_enumeration
Validate that value is one of the values in the enumeration.
validate_id
Validate an ID value: check that the value is a valid XML Name and that no duplicate ID values exist in the document.
validate_id_ref
Validate an IDREF value: check that the referenced ID exists in the document.
validate_id_refs
Validate IDREFS (whitespace-separated list of IDREF values).
validate_name
Validate whether value is a valid XML Name.
validate_name_space
Modern 2-arg form, upstream tree.c xmlValidateName(value, space).
validate_name_value
Upstream xmlValidateNameValue(value) — 1 if valid, 0 otherwise.
validate_names
Validate whether value is a whitespace-separated list of XML Names.
validate_names_value
Upstream xmlValidateNamesValue(value) — 1 if valid, 0 otherwise.
validate_ncname
Modern 2-arg form, upstream tree.c xmlValidateNCName(value, space).
validate_nmtoken
Validate whether value is a valid XML NMTOKEN.
validate_nmtoken_space
Modern 2-arg form, upstream tree.c xmlValidateNMToken(value, space).
validate_nmtoken_value
Upstream xmlValidateNmtokenValue(value) — 1 if valid, 0 otherwise.
validate_nmtokens
Validate whether value is a whitespace-separated list of XML NMTOKENs.
validate_nmtokens_value
Upstream xmlValidateNmtokensValue(value) — 1 if valid, 0 otherwise.
validate_notation_decl
Upstream xmlValidateNotationDecl(ctxt, doc, nota): modern libxml2 has no validity constraint on notation declarations and returns 1 always (verified by disassembly of the system DSO: mov $1,%eax; ret).
validate_notation_use
Validate that notationName is a declared notation in the document’s DTD.
validate_one_attribute
Upstream xmlValidateOneAttribute(ctxt, doc, elem, attr, value).
validate_one_element
Upstream xmlValidateOneElement(ctxt, doc, elem) — validates a single element against its declaration (content model + attributes), WITHOUT recursing into children.
validate_one_namespace
Upstream xmlValidateOneNamespace(ctxt, doc, elem, prefix, ns, value) — namespace-declaration attribute validation.
validate_pop_element
Upstream xmlValidatePopElement(ctxt, doc, elem, qname): verify the parent content model completed and pop the validation state.
validate_push_cdata
Upstream xmlValidatePushCData(ctxt, data, len): character data is only legal as whitespace inside ELEMENT content.
validate_push_element
Upstream xmlValidatePushElement(ctxt, doc, elem, qname): validate a start tag against the parent’s content model and push the new element’s validation state.
validate_qname
Modern 2-arg form, upstream tree.c xmlValidateQName(value, space).
validate_root
Validate the root element of a document.