XML XSD Sequences
A complex type can contain child elements and attributes. A sequence says which children appear and in what order; occurrence bounds say how many are allowed.
How it works
The packet contract requires name before quantity and optionally permits up to two notes. This keeps the data shape predictable for consumers. minOccurs defaults to one and maxOccurs defaults to one, so optional and repeated fields should be deliberate. Use unbounded only when the receiving application also has practical size limits. Schema cardinality and server resource limits solve different problems.
Run the code
Use Python 3 with lxml 6.1.1 in a separate virtual environment. The complete listing embeds its own XML and any schema or stylesheet; run python complex-content.py. It does not need Apache or MySQL. The shared restrictive parse function rejects declarations for untrusted input. The trusted DTD/entity and streaming lessons explicitly explain their separate fixed-input boundaries.
Download the complete complex-content.py source. Keep each lab in its own folder. Sources are served as text, not as public executable server scripts. Review the starting setup.
Example
from lxml import etree as E
class DenyExternal(E.Resolver):
def resolve(self, url, public_id, context):
raise ValueError("External resources are disabled")
def parse(text):
if "<!DOCTYPE" in text.upper() or "<!ENTITY" in text.upper():
raise ValueError("Declarations are disabled for untrusted XML")
parser = E.XMLParser(resolve_entities=False, load_dtd=False,
no_network=True, huge_tree=False)
parser.resolvers.add(DenyExternal())
return E.fromstring(text.encode("utf-8"), parser)
source = "<packet><name>Marigold</name><quantity>12</quantity><note>Keep dry</note></packet>"
root = parse(source)
schema_source = "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" ><xs:element name=\"packet\"><xs:complexType><xs:sequence><xs:element name=\"name\" type=\"xs:string\"/><xs:element name=\"quantity\" type=\"xs:nonNegativeInteger\"/><xs:element name=\"note\" type=\"xs:string\" minOccurs=\"0\" maxOccurs=\"2\"/></xs:sequence></xs:complexType></xs:element></xs:schema>"
contract = E.XMLSchema(parse(schema_source))
print(contract.validate(root))
Expected result
True
The order and number of children satisfy the contract. Swapping quantity and name would fail this sequence even though both fields remain present. This is a schema design decision, not a universal XML rule.
Check the exact contract in the XML specification, XPath 1.0, the XSD 1.0 primer, lxml validation documentation and Saxon’s processor documentation.