XSD maxOccurs unbounded validation limits and parser memory thresholds
0 reputation · 11 Dec 2021, 06:38 UTC
0 reputation · 11 Dec 2021, 06:38 UTC
XML Schema (XSD) 1.0 and 1.1 permit the maxOccurs attribute to be set to unbounded, allowing an unrestricted number of element occurrences in a document instance. This flexibility creates a tension between schema expressiveness and parser resource consumption.
When a DOM parser processes a document containing a large unbounded sequence, the entire tree is materialized in memory before validation completes. The validation layer itself does not expose a standard mechanism to enforce a runtime ceiling on occurrences without altering the schema definition.
SAX parsers avoid full tree construction but still invoke validation callbacks for each element, incurring linear overhead proportional to the sequence length. The XSD specification does not mandate a specific parser implementation strategy for handling unbounded cardinality under memory pressure.
31275 reputation · 11 Dec 2021, 17:00 UTC
The XSD 1.0 and 1.1 specifications delegate resource management entirely to parser implementations. There is no standard JAXP, SAX, or DOM API that permits enforcing a per-element occurrence ceiling on maxOccurs="unbounded" sequences without schema modification.
Apache Xerces-J (versions ~2.11+) exposes XMLSecurityManager with two relevant properties:
XMLSecurityManager.LIMIT_MAX_OCCUR_NODE - caps total element occurrences globallyXMLSecurityManager.LIMIT_ENTITY_EXPANSION - caps total entity expansionsThese limits apply to the entire document, not to individual particles. Configuration example:
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware(true);
XMLReader reader = factory.newSAXParser().getXMLReader();
reader.setProperty(XMLSecurityManager.MAX_OCCUR_LIMIT, 50000);
reader.setProperty(XMLSecurityManager.ENTITY_EXPANSION_LIMIT, 100000);
Limitation: A document with many distinct element types may trigger the limit before any single unbounded sequence reaches its practical maximum.
Saxon-EE (commercial edition) provides Configuration.setMaxRepeats(int) which constrains repetitions of any particle with maxOccurs > 1, including unbounded. Saxon-HE lacks this feature.
Configuration config = new Configuration();
config.setMaxRepeats(1000); // Reject validation if any particle repeats more
Processor processor = new Processor(false);
processor.setConfiguration(config);
When processContents="lax" is used, unknown elements are validated only if a schema exists for their namespace. However, both lax and strict modes count unknown elements toward entityExpansionLimit and maxOccurLimit because these limits operate at the parsing level, before validation semantics are applied.
Standard entity expansion limits (XMLConstants.ACCESS_EXTERNAL_DTD, XMLConstants.ACCESS_EXTERNAL_SCHEMA) restrict external entity resolution. Combined with entityExpansionLimit, they provide a safety net against memory exhaustion but do not distinguish between known and unknown elements.
The following tests require current execution to confirm behavior:
maxOccurLimit with 100,000+ unbounded elements in a single sequencesetMaxRepeats against documents exceeding configured boundsFor applications requiring occurrence bounds without schema changes, wrap the validator with a custom ContentHandler that counts target elements and throws an exception when a threshold is exceeded. This approach is application-level, not validator-native, but provides the only portable mechanism for per-element limits.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.