sup_xml_core/dtd/model.rs
1//! Type-level DTD vocabulary — Element/Attribute decls and content models.
2
3/// An `<!ELEMENT name model>` declaration.
4#[derive(Debug, Clone)]
5pub struct ElementDecl {
6 pub name: String,
7 pub content: ContentModel,
8}
9
10/// XML 1.0 § 3.2 element content classifications.
11#[derive(Debug, Clone)]
12pub enum ContentModel {
13 /// `EMPTY` — no children of any kind allowed.
14 Empty,
15 /// `ANY` — anything goes (no validation against this element).
16 Any,
17 /// Mixed content per § 3.2.2 [51]. Either `(#PCDATA)*` (no
18 /// child elements named, `choices` empty) or
19 /// `(#PCDATA | a | b ...)*`. Always carries the trailing `*`
20 /// implicitly when `choices` is non-empty.
21 Mixed { choices: Vec<String> },
22 /// Children content per § 3.2.1 [47]. A nested group of
23 /// element-name particles with sequence/choice/occurrence
24 /// structure.
25 Children(Group),
26}
27
28/// One Sequence or Choice with its own occurrence indicator —
29/// matches the grammar in § 3.2.1 [49] / [50].
30#[derive(Debug, Clone)]
31pub struct Group {
32 pub kind: GroupKind,
33 pub items: Vec<Particle>,
34 pub occur: Occurrence,
35}
36
37#[derive(Debug, Clone, Copy, PartialEq, Eq)]
38pub enum GroupKind { Sequence, Choice }
39
40/// One element-name reference or a nested Group, with its own
41/// `?` / `*` / `+` indicator.
42#[derive(Debug, Clone)]
43pub struct Particle {
44 pub item: Item,
45 pub occur: Occurrence,
46}
47
48#[derive(Debug, Clone)]
49pub enum Item {
50 /// `Name` per [48] — refers to another element by GI.
51 Name(String),
52 /// Nested parenthesised group.
53 Group(Box<Group>),
54}
55
56/// `?` / `*` / `+` per § 3.2.1 [47]. `One` = no suffix.
57#[derive(Debug, Clone, Copy, PartialEq, Eq)]
58pub enum Occurrence {
59 One,
60 ZeroOrOne,
61 ZeroOrMore,
62 OneOrMore,
63}
64
65/// A reference to one internal/external-subset declaration in source
66/// order, so the DTD serializer can reproduce libxml2's declaration
67/// ordering (it walks `xmlDtd.children`, which is source order).
68#[derive(Debug, Clone)]
69pub enum DeclRef {
70 /// `<!ELEMENT name …>` — index by name into `Dtd::elements`.
71 Element(String),
72 /// `<!ATTLIST name …>` — index by name into `Dtd::attlists`.
73 Attlist(String),
74 /// `<!ENTITY …>` — index into `Dtd::entities`.
75 Entity(usize),
76}
77
78/// An `<!ENTITY name ...>` general-entity declaration — internal (with a
79/// literal replacement text) or external (SYSTEM/PUBLIC, optionally
80/// `NDATA`). Mirrors the fields lxml reads off libxml2's `xmlEntity`
81/// and what the DTD serializer reconstructs.
82#[derive(Debug, Clone)]
83pub struct EntityDecl {
84 pub name: String,
85 /// `true` for a parameter entity (`<!ENTITY % name …>`).
86 pub parameter: bool,
87 /// Replacement text as written, before reference expansion
88 /// (libxml2's `orig`). `None` for external entities.
89 pub orig: Option<String>,
90 /// Replacement text after character/entity-reference expansion
91 /// (libxml2's `content`). `None` for external entities.
92 pub content: Option<String>,
93 /// `SYSTEM` identifier (or the second literal of `PUBLIC`).
94 pub system_id: Option<String>,
95 /// `PUBLIC` identifier.
96 pub public_id: Option<String>,
97 /// `NDATA` notation name — present only for unparsed entities.
98 pub ndata: Option<String>,
99}
100
101/// One row of an `<!ATTLIST element name type default>` block.
102#[derive(Debug, Clone)]
103pub struct AttDecl {
104 pub name: String,
105 pub att_type: AttType,
106 pub default: AttDefault,
107}
108
109/// XML 1.0 § 3.3.1 attribute types.
110#[derive(Debug, Clone)]
111pub enum AttType {
112 CData,
113 Id,
114 IdRef,
115 IdRefs,
116 Entity,
117 Entities,
118 Nmtoken,
119 Nmtokens,
120 /// `NOTATION (n1 | n2 | ...)`. Stored verbatim for completeness;
121 /// the validator does not currently cross-check against `<!NOTATION>`
122 /// declarations.
123 Notation(Vec<String>),
124 /// `(v1 | v2 | ...)` — enumerated. The attribute value at the
125 /// document body must match one of these literally.
126 Enumeration(Vec<String>),
127}
128
129/// XML 1.0 § 3.3.2 default declarations.
130#[derive(Debug, Clone)]
131pub enum AttDefault {
132 /// `#REQUIRED`
133 Required,
134 /// `#IMPLIED`
135 Implied,
136 /// `#FIXED "value"` — attribute must equal `value` if present.
137 Fixed(String),
138 /// Literal default value — supplied if the attribute is absent
139 /// from the document body. v0.1 doesn't perform defaulting at
140 /// parse time, so the validator just ignores this and accepts
141 /// either presence or absence.
142 Default(String),
143}