Coverage Report

Created: 2026-01-30 06:08

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/quick-xml-0.38.4/src/name.rs
Line
Count
Source
1
//! Module for handling names according to the W3C [Namespaces in XML 1.1 (Second Edition)][spec]
2
//! specification
3
//!
4
//! [spec]: https://www.w3.org/TR/xml-names11
5
6
use crate::events::attributes::Attribute;
7
use crate::events::{BytesStart, Event};
8
use crate::utils::write_byte_string;
9
use memchr::memchr;
10
use std::fmt::{self, Debug, Formatter};
11
use std::iter::FusedIterator;
12
13
/// Some namespace was invalid
14
#[derive(Debug, Clone, PartialEq, Eq)]
15
pub enum NamespaceError {
16
    /// Specified namespace prefix is unknown, cannot resolve namespace for it
17
    UnknownPrefix(Vec<u8>),
18
    /// Attempts to bind the `xml` prefix to something other than `http://www.w3.org/XML/1998/namespace`.
19
    ///
20
    /// `xml` prefix can be bound only to `http://www.w3.org/XML/1998/namespace`.
21
    ///
22
    /// Contains the namespace to which `xml` tried to be bound.
23
    InvalidXmlPrefixBind(Vec<u8>),
24
    /// Attempts to bind the `xmlns` prefix.
25
    ///
26
    /// `xmlns` prefix is always bound to `http://www.w3.org/2000/xmlns/` and cannot be bound
27
    /// to any other namespace or even to `http://www.w3.org/2000/xmlns/`.
28
    ///
29
    /// Contains the namespace to which `xmlns` tried to be bound.
30
    InvalidXmlnsPrefixBind(Vec<u8>),
31
    /// Attempts to bind some prefix (except `xml`) to `http://www.w3.org/XML/1998/namespace`.
32
    ///
33
    /// Only `xml` prefix can be bound to `http://www.w3.org/XML/1998/namespace`.
34
    ///
35
    /// Contains the prefix that is tried to be bound.
36
    InvalidPrefixForXml(Vec<u8>),
37
    /// Attempts to bind some prefix to `http://www.w3.org/2000/xmlns/`.
38
    ///
39
    /// `http://www.w3.org/2000/xmlns/` cannot be bound to any prefix, even to `xmlns`.
40
    ///
41
    /// Contains the prefix that is tried to be bound.
42
    InvalidPrefixForXmlns(Vec<u8>),
43
}
44
45
impl fmt::Display for NamespaceError {
46
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
47
0
        match self {
48
0
            Self::UnknownPrefix(prefix) => {
49
0
                f.write_str("unknown namespace prefix '")?;
50
0
                write_byte_string(f, prefix)?;
51
0
                f.write_str("'")
52
            }
53
0
            Self::InvalidXmlPrefixBind(namespace) => {
54
0
                f.write_str("the namespace prefix 'xml' cannot be bound to '")?;
55
0
                write_byte_string(f, namespace)?;
56
0
                f.write_str("'")
57
            }
58
0
            Self::InvalidXmlnsPrefixBind(namespace) => {
59
0
                f.write_str("the namespace prefix 'xmlns' cannot be bound to '")?;
60
0
                write_byte_string(f, namespace)?;
61
0
                f.write_str("'")
62
            }
63
0
            Self::InvalidPrefixForXml(prefix) => {
64
0
                f.write_str("the namespace prefix '")?;
65
0
                write_byte_string(f, prefix)?;
66
0
                f.write_str("' cannot be bound to 'http://www.w3.org/XML/1998/namespace'")
67
            }
68
0
            Self::InvalidPrefixForXmlns(prefix) => {
69
0
                f.write_str("the namespace prefix '")?;
70
0
                write_byte_string(f, prefix)?;
71
0
                f.write_str("' cannot be bound to 'http://www.w3.org/2000/xmlns/'")
72
            }
73
        }
74
0
    }
75
}
76
77
impl std::error::Error for NamespaceError {}
78
79
////////////////////////////////////////////////////////////////////////////////////////////////////
80
81
/// A [qualified name] of an element or an attribute, including an optional
82
/// namespace [prefix](Prefix) and a [local name](LocalName).
83
///
84
/// [qualified name]: https://www.w3.org/TR/xml-names11/#dt-qualname
85
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
86
#[cfg_attr(feature = "serde-types", derive(serde::Deserialize, serde::Serialize))]
87
pub struct QName<'a>(pub &'a [u8]);
88
impl<'a> QName<'a> {
89
    /// Converts this name to an internal slice representation.
90
    #[inline(always)]
91
0
    pub const fn into_inner(self) -> &'a [u8] {
92
0
        self.0
93
0
    }
94
95
    /// Returns local part of this qualified name.
96
    ///
97
    /// All content up to and including the first `:` character is removed from
98
    /// the tag name.
99
    ///
100
    /// # Examples
101
    ///
102
    /// ```
103
    /// # use quick_xml::name::QName;
104
    /// let simple = QName(b"simple-name");
105
    /// assert_eq!(simple.local_name().as_ref(), b"simple-name");
106
    ///
107
    /// let qname = QName(b"namespace:simple-name");
108
    /// assert_eq!(qname.local_name().as_ref(), b"simple-name");
109
    /// ```
110
0
    pub fn local_name(&self) -> LocalName<'a> {
111
0
        LocalName(self.index().map_or(self.0, |i| &self.0[i + 1..]))
112
0
    }
113
114
    /// Returns namespace part of this qualified name or `None` if namespace part
115
    /// is not defined (symbol `':'` not found).
116
    ///
117
    /// # Examples
118
    ///
119
    /// ```
120
    /// # use std::convert::AsRef;
121
    /// # use quick_xml::name::QName;
122
    /// let simple = QName(b"simple-name");
123
    /// assert_eq!(simple.prefix(), None);
124
    ///
125
    /// let qname = QName(b"prefix:simple-name");
126
    /// assert_eq!(qname.prefix().as_ref().map(|n| n.as_ref()), Some(b"prefix".as_ref()));
127
    /// ```
128
0
    pub fn prefix(&self) -> Option<Prefix<'a>> {
129
0
        self.index().map(|i| Prefix(&self.0[..i]))
130
0
    }
131
132
    /// The same as `(qname.local_name(), qname.prefix())`, but does only one
133
    /// lookup for a `':'` symbol.
134
0
    pub fn decompose(&self) -> (LocalName<'a>, Option<Prefix<'a>>) {
135
0
        match self.index() {
136
0
            None => (LocalName(self.0), None),
137
0
            Some(i) => (LocalName(&self.0[i + 1..]), Some(Prefix(&self.0[..i]))),
138
        }
139
0
    }
140
141
    /// If that `QName` represents `"xmlns"` series of names, returns `Some`,
142
    /// otherwise `None` is returned.
143
    ///
144
    /// # Examples
145
    ///
146
    /// ```
147
    /// # use quick_xml::name::{QName, PrefixDeclaration};
148
    /// let qname = QName(b"xmlns");
149
    /// assert_eq!(qname.as_namespace_binding(), Some(PrefixDeclaration::Default));
150
    ///
151
    /// let qname = QName(b"xmlns:prefix");
152
    /// assert_eq!(qname.as_namespace_binding(), Some(PrefixDeclaration::Named(b"prefix")));
153
    ///
154
    /// // Be aware that this method does not check the validity of the prefix - it can be empty!
155
    /// let qname = QName(b"xmlns:");
156
    /// assert_eq!(qname.as_namespace_binding(), Some(PrefixDeclaration::Named(b"")));
157
    ///
158
    /// let qname = QName(b"other-name");
159
    /// assert_eq!(qname.as_namespace_binding(), None);
160
    ///
161
    /// // https://www.w3.org/TR/xml-names11/#xmlReserved
162
    /// let qname = QName(b"xmlns-reserved-name");
163
    /// assert_eq!(qname.as_namespace_binding(), None);
164
    /// ```
165
0
    pub fn as_namespace_binding(&self) -> Option<PrefixDeclaration<'a>> {
166
0
        if self.0.starts_with(b"xmlns") {
167
0
            return match self.0.get(5) {
168
0
                None => Some(PrefixDeclaration::Default),
169
0
                Some(&b':') => Some(PrefixDeclaration::Named(&self.0[6..])),
170
0
                _ => None,
171
            };
172
0
        }
173
0
        None
174
0
    }
175
176
    /// Returns the index in the name where prefix ended
177
    #[inline(always)]
178
0
    fn index(&self) -> Option<usize> {
179
0
        memchr(b':', self.0)
180
0
    }
181
}
182
impl<'a> Debug for QName<'a> {
183
0
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
184
0
        write!(f, "QName(")?;
185
0
        write_byte_string(f, self.0)?;
186
0
        write!(f, ")")
187
0
    }
188
}
189
impl<'a> AsRef<[u8]> for QName<'a> {
190
    #[inline]
191
0
    fn as_ref(&self) -> &[u8] {
192
0
        self.0
193
0
    }
194
}
195
196
////////////////////////////////////////////////////////////////////////////////////////////////////
197
198
/// A [local (unqualified) name] of an element or an attribute, i.e. a name
199
/// without [prefix](Prefix).
200
///
201
/// [local (unqualified) name]: https://www.w3.org/TR/xml-names11/#dt-localname
202
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
203
#[cfg_attr(feature = "serde-types", derive(serde::Deserialize, serde::Serialize))]
204
pub struct LocalName<'a>(pub(crate) &'a [u8]);
205
impl<'a> LocalName<'a> {
206
    /// Converts this name to an internal slice representation.
207
    #[inline(always)]
208
0
    pub const fn into_inner(self) -> &'a [u8] {
209
0
        self.0
210
0
    }
211
}
212
impl<'a> Debug for LocalName<'a> {
213
0
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
214
0
        write!(f, "LocalName(")?;
215
0
        write_byte_string(f, self.0)?;
216
0
        write!(f, ")")
217
0
    }
218
}
219
impl<'a> AsRef<[u8]> for LocalName<'a> {
220
    #[inline]
221
0
    fn as_ref(&self) -> &[u8] {
222
0
        self.0
223
0
    }
224
}
225
impl<'a> From<QName<'a>> for LocalName<'a> {
226
    /// Creates `LocalName` from a [`QName`]
227
    ///
228
    /// # Examples
229
    ///
230
    /// ```
231
    /// # use quick_xml::name::{LocalName, QName};
232
    ///
233
    /// let local: LocalName = QName(b"unprefixed").into();
234
    /// assert_eq!(local.as_ref(), b"unprefixed");
235
    ///
236
    /// let local: LocalName = QName(b"some:prefix").into();
237
    /// assert_eq!(local.as_ref(), b"prefix");
238
    /// ```
239
    #[inline]
240
0
    fn from(name: QName<'a>) -> Self {
241
0
        Self(name.index().map_or(name.0, |i| &name.0[i + 1..]))
242
0
    }
243
}
244
245
////////////////////////////////////////////////////////////////////////////////////////////////////
246
247
/// A [namespace prefix] part of the [qualified name](QName) of an element tag
248
/// or an attribute: a `prefix` in `<prefix:local-element-name>` or
249
/// `prefix:local-attribute-name="attribute value"`.
250
///
251
/// [namespace prefix]: https://www.w3.org/TR/xml-names11/#dt-prefix
252
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
253
#[cfg_attr(feature = "serde-types", derive(serde::Deserialize, serde::Serialize))]
254
pub struct Prefix<'a>(&'a [u8]);
255
impl<'a> Prefix<'a> {
256
    /// Extracts internal slice
257
    #[inline(always)]
258
0
    pub const fn into_inner(self) -> &'a [u8] {
259
0
        self.0
260
0
    }
261
262
    /// Checks if this prefix is a special prefix `xml`.
263
    #[inline(always)]
264
0
    pub const fn is_xml(&self) -> bool {
265
0
        matches!(self.0, b"xml")
266
0
    }
267
268
    /// Checks if this prefix is a special prefix `xmlns`.
269
    #[inline(always)]
270
0
    pub const fn is_xmlns(&self) -> bool {
271
0
        matches!(self.0, b"xmlns")
272
0
    }
273
}
274
impl<'a> Debug for Prefix<'a> {
275
0
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
276
0
        write!(f, "Prefix(")?;
277
0
        write_byte_string(f, self.0)?;
278
0
        write!(f, ")")
279
0
    }
280
}
281
impl<'a> AsRef<[u8]> for Prefix<'a> {
282
    #[inline]
283
0
    fn as_ref(&self) -> &[u8] {
284
0
        self.0
285
0
    }
286
}
287
288
////////////////////////////////////////////////////////////////////////////////////////////////////
289
290
/// A namespace prefix declaration, `xmlns` or `xmlns:<name>`, as defined in
291
/// [XML Schema specification](https://www.w3.org/TR/xml-names11/#ns-decl)
292
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
293
pub enum PrefixDeclaration<'a> {
294
    /// XML attribute binds a default namespace. Corresponds to `xmlns` in `xmlns="..."`
295
    Default,
296
    /// XML attribute binds a specified prefix to a namespace. Corresponds to a
297
    /// `prefix` in `xmlns:prefix="..."`, which is stored as payload of this variant.
298
    Named(&'a [u8]),
299
}
300
impl<'a> Debug for PrefixDeclaration<'a> {
301
0
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
302
0
        match self {
303
0
            Self::Default => f.write_str("PrefixDeclaration::Default"),
304
0
            Self::Named(prefix) => {
305
0
                f.write_str("PrefixDeclaration::Named(")?;
306
0
                write_byte_string(f, prefix)?;
307
0
                f.write_str(")")
308
            }
309
        }
310
0
    }
311
}
312
313
////////////////////////////////////////////////////////////////////////////////////////////////////
314
315
/// A [namespace name] that is declared in a `xmlns[:prefix]="namespace name"`.
316
///
317
/// [namespace name]: https://www.w3.org/TR/xml-names11/#dt-NSName
318
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
319
#[cfg_attr(feature = "serde-types", derive(serde::Deserialize, serde::Serialize))]
320
pub struct Namespace<'a>(pub &'a [u8]);
321
impl<'a> Namespace<'a> {
322
    /// Converts this namespace to an internal slice representation.
323
    ///
324
    /// This is [non-normalized] attribute value, i.e. any entity references is
325
    /// not expanded and space characters are not removed. This means, that
326
    /// different byte slices, returned from this method, can represent the same
327
    /// namespace and would be treated by parser as identical.
328
    ///
329
    /// For example, if the entity **eacute** has been defined to be **é**,
330
    /// the empty tags below all contain namespace declarations binding the
331
    /// prefix `p` to the same [IRI reference], `http://example.org/rosé`.
332
    ///
333
    /// ```xml
334
    /// <p:foo xmlns:p="http://example.org/rosé" />
335
    /// <p:foo xmlns:p="http://example.org/ros&#xe9;" />
336
    /// <p:foo xmlns:p="http://example.org/ros&#xE9;" />
337
    /// <p:foo xmlns:p="http://example.org/ros&#233;" />
338
    /// <p:foo xmlns:p="http://example.org/ros&eacute;" />
339
    /// ```
340
    ///
341
    /// This is because XML entity references are expanded during attribute value
342
    /// normalization.
343
    ///
344
    /// [non-normalized]: https://www.w3.org/TR/xml11/#AVNormalize
345
    /// [IRI reference]: https://datatracker.ietf.org/doc/html/rfc3987
346
    #[inline(always)]
347
0
    pub const fn into_inner(self) -> &'a [u8] {
348
0
        self.0
349
0
    }
350
    //TODO: implement value normalization and use it when comparing namespaces
351
}
352
impl<'a> Debug for Namespace<'a> {
353
0
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
354
0
        write!(f, "Namespace(")?;
355
0
        write_byte_string(f, self.0)?;
356
0
        write!(f, ")")
357
0
    }
358
}
359
impl<'a> AsRef<[u8]> for Namespace<'a> {
360
    #[inline]
361
0
    fn as_ref(&self) -> &[u8] {
362
0
        self.0
363
0
    }
364
}
365
366
////////////////////////////////////////////////////////////////////////////////////////////////////
367
368
/// Result of [prefix] resolution which creates by [`NamespaceResolver::resolve`], [`NsReader::resolve_attribute`],
369
/// [`NsReader::resolve_element`], [`NsReader::read_resolved_event`] and
370
/// [`NsReader::read_resolved_event_into`] methods.
371
///
372
/// [prefix]: Prefix
373
/// [`NsReader::resolve_attribute`]: crate::reader::NsReader::resolve_attribute
374
/// [`NsReader::resolve_element`]: crate::reader::NsReader::resolve_element
375
/// [`NsReader::read_resolved_event`]: crate::reader::NsReader::read_resolved_event
376
/// [`NsReader::read_resolved_event_into`]: crate::reader::NsReader::read_resolved_event_into
377
#[derive(Clone, PartialEq, Eq, Hash)]
378
pub enum ResolveResult<'ns> {
379
    /// Qualified name does not contain prefix, and resolver does not define
380
    /// default namespace, so name is not bound to any namespace
381
    Unbound,
382
    /// [`Prefix`] resolved to the specified namespace
383
    Bound(Namespace<'ns>),
384
    /// Specified prefix was not found in scope
385
    Unknown(Vec<u8>),
386
}
387
impl<'ns> Debug for ResolveResult<'ns> {
388
0
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
389
0
        match self {
390
0
            Self::Unbound => write!(f, "Unbound"),
391
0
            Self::Bound(ns) => write!(f, "Bound({:?})", ns),
392
0
            Self::Unknown(p) => {
393
0
                write!(f, "Unknown(")?;
394
0
                write_byte_string(f, p)?;
395
0
                write!(f, ")")
396
            }
397
        }
398
0
    }
399
}
400
401
impl<'ns> TryFrom<ResolveResult<'ns>> for Option<Namespace<'ns>> {
402
    type Error = NamespaceError;
403
404
    /// Try to convert this result to an optional namespace and returns
405
    /// [`NamespaceError::UnknownPrefix`] if this result represents unknown prefix
406
0
    fn try_from(result: ResolveResult<'ns>) -> Result<Self, NamespaceError> {
407
        use ResolveResult::*;
408
409
0
        match result {
410
0
            Unbound => Ok(None),
411
0
            Bound(ns) => Ok(Some(ns)),
412
0
            Unknown(p) => Err(NamespaceError::UnknownPrefix(p)),
413
        }
414
0
    }
415
}
416
417
////////////////////////////////////////////////////////////////////////////////////////////////////
418
419
/// An entry that contains index into the buffer with namespace bindings.
420
///
421
/// Defines a mapping from *[namespace prefix]* to *[namespace name]*.
422
/// If prefix is empty, defines a *default namespace* binding that applies to
423
/// unprefixed element names (unprefixed attribute names do not bind to any
424
/// namespace and they processing is dependent on the element in which their
425
/// defined).
426
///
427
/// [namespace prefix]: https://www.w3.org/TR/xml-names11/#dt-prefix
428
/// [namespace name]: https://www.w3.org/TR/xml-names11/#dt-NSName
429
#[derive(Debug, Clone)]
430
struct NamespaceBinding {
431
    /// Index of the namespace in the buffer
432
    start: usize,
433
    /// Length of the prefix
434
    /// * if greater than zero, then binds this namespace to the slice
435
    ///   `[start..start + prefix_len]` in the buffer.
436
    /// * else defines the current default namespace.
437
    prefix_len: usize,
438
    /// The length of a namespace name (the URI) of this namespace declaration.
439
    /// Name started just after prefix and extend for `value_len` bytes.
440
    ///
441
    /// The XML standard [specifies] that an empty namespace value 'removes' a namespace declaration
442
    /// for the extent of its scope. For prefix declarations that's not very interesting, but it is
443
    /// vital for default namespace declarations. With `xmlns=""` you can revert back to the default
444
    /// behaviour of leaving unqualified element names unqualified.
445
    ///
446
    /// [specifies]: https://www.w3.org/TR/xml-names11/#scoping
447
    value_len: usize,
448
    /// Level of nesting at which this namespace was declared. The declaring element is included,
449
    /// i.e., a declaration on the document root has `level = 1`.
450
    /// This is used to pop the namespace when the element gets closed.
451
    level: u16,
452
}
453
454
impl NamespaceBinding {
455
    /// Get the namespace prefix, bound to this namespace declaration, or `None`,
456
    /// if this declaration is for default namespace (`xmlns="..."`).
457
    #[inline]
458
0
    fn prefix<'b>(&self, ns_buffer: &'b [u8]) -> Option<Prefix<'b>> {
459
0
        if self.prefix_len == 0 {
460
0
            None
461
        } else {
462
0
            Some(Prefix(&ns_buffer[self.start..self.start + self.prefix_len]))
463
        }
464
0
    }
465
466
    /// Gets the namespace name (the URI) slice out of namespace buffer
467
    ///
468
    /// Returns `None` if namespace for this prefix was explicitly removed from
469
    /// scope, using `xmlns[:prefix]=""`
470
    #[inline]
471
0
    fn namespace<'ns>(&self, buffer: &'ns [u8]) -> ResolveResult<'ns> {
472
0
        if self.value_len == 0 {
473
0
            ResolveResult::Unbound
474
        } else {
475
0
            let start = self.start + self.prefix_len;
476
0
            ResolveResult::Bound(Namespace(&buffer[start..start + self.value_len]))
477
        }
478
0
    }
479
}
480
481
/// A storage for currently defined namespace bindings, which is used to resolve
482
/// prefixes into namespaces.
483
///
484
/// Holds all internal logic to push/pop namespaces with their levels.
485
#[derive(Debug, Clone)]
486
pub struct NamespaceResolver {
487
    /// Buffer that contains names of namespace prefixes (the part between `xmlns:`
488
    /// and an `=`) and namespace values.
489
    buffer: Vec<u8>,
490
    /// A stack of namespace bindings to prefixes that currently in scope
491
    bindings: Vec<NamespaceBinding>,
492
    /// The number of open tags at the moment. We need to keep track of this to know which namespace
493
    /// declarations to remove when we encounter an `End` event.
494
    nesting_level: u16,
495
}
496
497
/// That constant define the one of [reserved namespaces] for the xml standard.
498
///
499
/// The prefix `xml` is by definition bound to the namespace name
500
/// `http://www.w3.org/XML/1998/namespace`. It may, but need not, be declared, and must not be
501
/// undeclared or bound to any other namespace name. Other prefixes must not be bound to this
502
/// namespace name, and it must not be declared as the default namespace.
503
///
504
/// [reserved namespaces]: https://www.w3.org/TR/xml-names11/#xmlReserved
505
const RESERVED_NAMESPACE_XML: (Prefix, Namespace) = (
506
    Prefix(b"xml"),
507
    Namespace(b"http://www.w3.org/XML/1998/namespace"),
508
);
509
/// That constant define the one of [reserved namespaces] for the xml standard.
510
///
511
/// The prefix `xmlns` is used only to declare namespace bindings and is by definition bound
512
/// to the namespace name `http://www.w3.org/2000/xmlns/`. It must not be declared or
513
/// undeclared. Other prefixes must not be bound to this namespace name, and it must not be
514
/// declared as the default namespace. Element names must not have the prefix `xmlns`.
515
///
516
/// [reserved namespaces]: https://www.w3.org/TR/xml-names11/#xmlReserved
517
const RESERVED_NAMESPACE_XMLNS: (Prefix, Namespace) = (
518
    Prefix(b"xmlns"),
519
    Namespace(b"http://www.w3.org/2000/xmlns/"),
520
);
521
522
impl Default for NamespaceResolver {
523
0
    fn default() -> Self {
524
0
        let mut buffer = Vec::new();
525
0
        let mut bindings = Vec::new();
526
0
        for ent in &[RESERVED_NAMESPACE_XML, RESERVED_NAMESPACE_XMLNS] {
527
0
            let prefix = ent.0.into_inner();
528
0
            let uri = ent.1.into_inner();
529
0
            bindings.push(NamespaceBinding {
530
0
                start: buffer.len(),
531
0
                prefix_len: prefix.len(),
532
0
                value_len: uri.len(),
533
0
                level: 0,
534
0
            });
535
0
            buffer.extend(prefix);
536
0
            buffer.extend(uri);
537
0
        }
538
539
0
        Self {
540
0
            buffer,
541
0
            bindings,
542
0
            nesting_level: 0,
543
0
        }
544
0
    }
545
}
546
547
impl NamespaceResolver {
548
    /// Adds new binding of prefix to namespace, returns the result of operation.
549
    ///
550
    /// Binding will be added on current nesting level and will be removed, when
551
    /// level will be [popped out].
552
    ///
553
    /// The operation may fail if you try to (re-)declare reserved prefixes `xml` and `xmlns`.
554
    ///
555
    /// Note, that method does not check if namespace was already added on that level.
556
    /// Use `resolver.bindings_of(resolver.level()).any()` if you want to check that.
557
    /// New definition will be added and replace the old.
558
    ///
559
    /// Implementation detail: memory occupied by old binding of that level still will be used.
560
    ///
561
    /// ```
562
    /// # use pretty_assertions::assert_eq;
563
    /// # use quick_xml::name::{Namespace, NamespaceResolver, PrefixDeclaration, QName, ResolveResult};
564
    /// #
565
    /// let mut resolver = NamespaceResolver::default();
566
    /// // names without prefix are unbound by default
567
    /// assert_eq!(
568
    ///     resolver.resolve_element(QName(b"name")).0,
569
    ///     ResolveResult::Unbound,
570
    /// );
571
    /// // names with undeclared prefix are unknown
572
    /// assert_eq!(
573
    ///     resolver.resolve_element(QName(b"ns:name")).0,
574
    ///     ResolveResult::Unknown(b"ns".to_vec()),
575
    /// );
576
    ///
577
    /// resolver.add(PrefixDeclaration::Default, Namespace(b"example.com"));
578
    /// resolver.add(PrefixDeclaration::Named(b"ns"), Namespace(b"my:namespace"));
579
    ///
580
    /// assert_eq!(
581
    ///     resolver.resolve_element(QName(b"name")).0,
582
    ///     ResolveResult::Bound(Namespace(b"example.com")),
583
    /// );
584
    /// assert_eq!(
585
    ///     resolver.resolve_element(QName(b"ns:name")).0,
586
    ///     ResolveResult::Bound(Namespace(b"my:namespace")),
587
    /// );
588
    ///
589
    /// // adding empty namespace clears the binding
590
    /// resolver.add(PrefixDeclaration::Default, Namespace(b""));
591
    /// resolver.add(PrefixDeclaration::Named(b"ns"), Namespace(b""));
592
    ///
593
    /// assert_eq!(
594
    ///     resolver.resolve_element(QName(b"name")).0,
595
    ///     ResolveResult::Unbound,
596
    /// );
597
    /// assert_eq!(
598
    ///     resolver.resolve_element(QName(b"ns:name")).0,
599
    ///     ResolveResult::Unknown(b"ns".to_vec()),
600
    /// );
601
    /// ```
602
    /// [popped out]: Self::pop
603
0
    pub fn add(
604
0
        &mut self,
605
0
        prefix: PrefixDeclaration,
606
0
        namespace: Namespace,
607
0
    ) -> Result<(), NamespaceError> {
608
0
        let level = self.nesting_level;
609
0
        match prefix {
610
0
            PrefixDeclaration::Default => {
611
0
                let start = self.buffer.len();
612
0
                self.buffer.extend_from_slice(namespace.0);
613
0
                self.bindings.push(NamespaceBinding {
614
0
                    start,
615
0
                    prefix_len: 0,
616
0
                    value_len: namespace.0.len(),
617
0
                    level,
618
0
                });
619
0
            }
620
0
            PrefixDeclaration::Named(b"xml") => {
621
0
                if namespace != RESERVED_NAMESPACE_XML.1 {
622
                    // error, `xml` prefix explicitly set to different value
623
0
                    return Err(NamespaceError::InvalidXmlPrefixBind(namespace.0.to_vec()));
624
0
                }
625
                // don't add another NamespaceEntry for the `xml` namespace prefix
626
            }
627
0
            PrefixDeclaration::Named(b"xmlns") => {
628
                // error, `xmlns` prefix explicitly set
629
0
                return Err(NamespaceError::InvalidXmlnsPrefixBind(namespace.0.to_vec()));
630
            }
631
0
            PrefixDeclaration::Named(prefix) => {
632
                // error, non-`xml` prefix set to xml uri
633
0
                if namespace == RESERVED_NAMESPACE_XML.1 {
634
0
                    return Err(NamespaceError::InvalidPrefixForXml(prefix.to_vec()));
635
                } else
636
                // error, non-`xmlns` prefix set to xmlns uri
637
0
                if namespace == RESERVED_NAMESPACE_XMLNS.1 {
638
0
                    return Err(NamespaceError::InvalidPrefixForXmlns(prefix.to_vec()));
639
0
                }
640
641
0
                let start = self.buffer.len();
642
0
                self.buffer.extend_from_slice(prefix);
643
0
                self.buffer.extend_from_slice(namespace.0);
644
0
                self.bindings.push(NamespaceBinding {
645
0
                    start,
646
0
                    prefix_len: prefix.len(),
647
0
                    value_len: namespace.0.len(),
648
0
                    level,
649
0
                });
650
            }
651
        }
652
0
        Ok(())
653
0
    }
654
655
    /// Begins a new scope and add to it all [namespace bindings] that found in
656
    /// the specified start element.
657
    ///
658
    /// [namespace bindings]: https://www.w3.org/TR/xml-names11/#dt-NSDecl
659
0
    pub fn push(&mut self, start: &BytesStart) -> Result<(), NamespaceError> {
660
0
        self.nesting_level += 1;
661
        // adds new namespaces for attributes starting with 'xmlns:' and for the 'xmlns'
662
        // (default namespace) attribute.
663
0
        for a in start.attributes().with_checks(false) {
664
0
            if let Ok(Attribute { key: k, value: v }) = a {
665
0
                if let Some(prefix) = k.as_namespace_binding() {
666
0
                    self.add(prefix, Namespace(&v))?;
667
0
                }
668
            } else {
669
0
                break;
670
            }
671
        }
672
0
        Ok(())
673
0
    }
674
675
    /// Ends a top-most scope by popping all [namespace bindings], that was added by
676
    /// last call to [`Self::push()`] and [`Self::add()`].
677
    ///
678
    /// [namespace bindings]: https://www.w3.org/TR/xml-names11/#dt-NSDecl
679
0
    pub fn pop(&mut self) {
680
0
        self.nesting_level = self.nesting_level.saturating_sub(1);
681
0
        let current_level = self.nesting_level;
682
        // from the back (most deeply nested scope), look for the first scope that is still valid
683
0
        match self.bindings.iter().rposition(|n| n.level <= current_level) {
684
            // none of the namespaces are valid, remove all of them
685
0
            None => {
686
0
                self.buffer.clear();
687
0
                self.bindings.clear();
688
0
            }
689
            // drop all namespaces past the last valid namespace
690
0
            Some(last_valid_pos) => {
691
0
                if let Some(len) = self.bindings.get(last_valid_pos + 1).map(|n| n.start) {
692
0
                    self.buffer.truncate(len);
693
0
                    self.bindings.truncate(last_valid_pos + 1);
694
0
                }
695
            }
696
        }
697
0
    }
698
699
    /// Resolves a potentially qualified **element name** or **attribute name**
700
    /// into _(namespace name, local name)_.
701
    ///
702
    /// _Qualified_ names have the form `local-name` or `prefix:local-name` where the `prefix`
703
    /// is defined on any containing XML element via `xmlns:prefix="the:namespace:uri"`.
704
    /// The namespace prefix can be defined on the same element as the name in question.
705
    ///
706
    /// The method returns following results depending on the `name` shape, `attribute` flag
707
    /// and the presence of the default namespace on element or any of its parents:
708
    ///
709
    /// |use_default|`xmlns="..."`|QName              |ResolveResult          |LocalName
710
    /// |-----------|-------------|-------------------|-----------------------|------------
711
    /// |`false`    |_(any)_      |`local-name`       |[`Unbound`]            |`local-name`
712
    /// |`false`    |_(any)_      |`prefix:local-name`|[`Bound`] / [`Unknown`]|`local-name`
713
    /// |`true`     |Not defined  |`local-name`       |[`Unbound`]            |`local-name`
714
    /// |`true`     |Defined      |`local-name`       |[`Bound`] (to `xmlns`) |`local-name`
715
    /// |`true`     |_(any)_      |`prefix:local-name`|[`Bound`] / [`Unknown`]|`local-name`
716
    ///
717
    /// # Parameters
718
    /// - `name`: probably qualified name to resolve;
719
    /// - `use_default`: whether to try to translate `None` prefix to the currently default namespace
720
    ///   (bound using `xmlns="default namespace"`) or return [`ResolveResult::Unbound`].
721
    ///   For attribute names this should be set to `false` and for element names to `true`.
722
    ///
723
    /// # Lifetimes
724
    ///
725
    /// - `'n`: lifetime of a name. Returned local name will be bound to the same
726
    ///   lifetime as the name in question.
727
    /// - returned namespace name will be bound to the resolver itself
728
    ///
729
    /// [`Bound`]: ResolveResult::Bound
730
    /// [`Unbound`]: ResolveResult::Unbound
731
    /// [`Unknown`]: ResolveResult::Unknown
732
    #[inline]
733
0
    pub fn resolve<'n>(
734
0
        &self,
735
0
        name: QName<'n>,
736
0
        use_default: bool,
737
0
    ) -> (ResolveResult<'_>, LocalName<'n>) {
738
0
        let (local_name, prefix) = name.decompose();
739
0
        (self.resolve_prefix(prefix, use_default), local_name)
740
0
    }
741
742
    /// Convenient method to call `resolve(name, true)`. May be used to clearly
743
    /// express that we want to resolve an element name, and not an attribute name.
744
    #[inline]
745
0
    pub fn resolve_element<'n>(&self, name: QName<'n>) -> (ResolveResult<'_>, LocalName<'n>) {
746
0
        self.resolve(name, true)
747
0
    }
748
749
    /// Convenient method to call `resolve(name, false)`. May be used to clearly
750
    /// express that we want to resolve an attribute name, and not an element name.
751
    #[inline]
752
0
    pub fn resolve_attribute<'n>(&self, name: QName<'n>) -> (ResolveResult<'_>, LocalName<'n>) {
753
0
        self.resolve(name, false)
754
0
    }
755
756
    /// Finds a [namespace name] for a given event, if applicable.
757
    ///
758
    /// Namespace is resolved only for [`Start`], [`Empty`] and [`End`] events.
759
    /// For all other events the concept of namespace is not defined, so
760
    /// a [`ResolveResult::Unbound`] is returned.
761
    ///
762
    /// # Examples
763
    ///
764
    /// ```
765
    /// # use pretty_assertions::assert_eq;
766
    /// use quick_xml::events::Event;
767
    /// use quick_xml::name::{Namespace, QName, ResolveResult::*};
768
    /// use quick_xml::reader::NsReader;
769
    ///
770
    /// let mut reader = NsReader::from_str(r#"
771
    ///     <x:tag1 xmlns:x="www.xxxx" xmlns:y="www.yyyy" att1 = "test">
772
    ///        <y:tag2><!--Test comment-->Test</y:tag2>
773
    ///        <y:tag2>Test 2</y:tag2>
774
    ///     </x:tag1>
775
    /// "#);
776
    /// reader.config_mut().trim_text(true);
777
    ///
778
    /// let mut count = 0;
779
    /// let mut txt = Vec::new();
780
    /// loop {
781
    ///     let event = reader.read_event().unwrap();
782
    ///     match reader.resolver().resolve_event(event) {
783
    ///         (Bound(Namespace(b"www.xxxx")), Event::Start(e)) => {
784
    ///             count += 1;
785
    ///             assert_eq!(e.local_name(), QName(b"tag1").into());
786
    ///         }
787
    ///         (Bound(Namespace(b"www.yyyy")), Event::Start(e)) => {
788
    ///             count += 1;
789
    ///             assert_eq!(e.local_name(), QName(b"tag2").into());
790
    ///         }
791
    ///         (_, Event::Start(_)) => unreachable!(),
792
    ///
793
    ///         (_, Event::Text(e)) => {
794
    ///             txt.push(e.decode().unwrap().into_owned())
795
    ///         }
796
    ///         (_, Event::Eof) => break,
797
    ///         _ => (),
798
    ///     }
799
    /// }
800
    /// assert_eq!(count, 3);
801
    /// assert_eq!(txt, vec!["Test".to_string(), "Test 2".to_string()]);
802
    /// ```
803
    ///
804
    /// [namespace name]: https://www.w3.org/TR/xml-names11/#dt-NSName
805
    /// [`Empty`]: Event::Empty
806
    /// [`Start`]: Event::Start
807
    /// [`End`]: Event::End
808
0
    pub fn resolve_event<'i>(&self, event: Event<'i>) -> (ResolveResult<'_>, Event<'i>) {
809
        use Event::*;
810
811
0
        match event {
812
0
            Empty(e) => (self.resolve_prefix(e.name().prefix(), true), Empty(e)),
813
0
            Start(e) => (self.resolve_prefix(e.name().prefix(), true), Start(e)),
814
0
            End(e) => (self.resolve_prefix(e.name().prefix(), true), End(e)),
815
0
            e => (ResolveResult::Unbound, e),
816
        }
817
0
    }
818
819
    /// Resolves given optional prefix (usually got from [`QName`]) into a corresponding namespace.
820
    ///
821
    /// # Parameters
822
    /// - `prefix`: prefix to resolve, usually result of [`QName::prefix()`];
823
    /// - `use_default`: whether to try to translate `None` prefix to the currently default namespace
824
    ///   (bound using `xmlns="default namespace"`) or return [`ResolveResult::Unbound`].
825
    ///   For attribute names this should be set to `false` and for element names to `true`.
826
0
    pub fn resolve_prefix(&self, prefix: Option<Prefix>, use_default: bool) -> ResolveResult<'_> {
827
        // Find the last defined binding that corresponds to the given prefix
828
0
        let mut iter = self.bindings.iter().rev();
829
0
        match (prefix, use_default) {
830
            // Attribute name has no explicit prefix -> Unbound
831
0
            (None, false) => ResolveResult::Unbound,
832
            // Element name has no explicit prefix -> find nearest xmlns binding
833
0
            (None, true) => match iter.find(|n| n.prefix_len == 0) {
834
0
                Some(n) => n.namespace(&self.buffer),
835
0
                None => ResolveResult::Unbound,
836
            },
837
            // Attribute or element name with explicit prefix
838
0
            (Some(p), _) => match iter.find(|n| n.prefix(&self.buffer) == prefix) {
839
0
                Some(n) if n.value_len != 0 => n.namespace(&self.buffer),
840
                // Not found or binding reset (corresponds to `xmlns:p=""`)
841
0
                _ => ResolveResult::Unknown(p.into_inner().to_vec()),
842
            },
843
        }
844
0
    }
845
846
    /// Returns all the bindings currently in effect except the default `xml` and `xmlns` bindings.
847
    ///
848
    /// # Examples
849
    ///
850
    /// This example shows what results the returned iterator would return after
851
    /// reading each event of a simple XML.
852
    ///
853
    /// ```
854
    /// # use pretty_assertions::assert_eq;
855
    /// use quick_xml::name::{Namespace, PrefixDeclaration};
856
    /// use quick_xml::NsReader;
857
    ///
858
    /// let src = "<root>
859
    ///   <a xmlns=\"a1\" xmlns:a=\"a2\">
860
    ///     <b xmlns=\"b1\" xmlns:b=\"b2\">
861
    ///       <c/>
862
    ///     </b>
863
    ///     <d/>
864
    ///   </a>
865
    /// </root>";
866
    /// let mut reader = NsReader::from_str(src);
867
    /// reader.config_mut().trim_text(true);
868
    /// // No bindings at the beginning
869
    /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![]);
870
    ///
871
    /// reader.read_resolved_event()?; // <root>
872
    /// // No bindings declared on root
873
    /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![]);
874
    ///
875
    /// reader.read_resolved_event()?; // <a>
876
    /// // Two bindings declared on "a"
877
    /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![
878
    ///     (PrefixDeclaration::Default, Namespace(b"a1")),
879
    ///     (PrefixDeclaration::Named(b"a"), Namespace(b"a2"))
880
    /// ]);
881
    ///
882
    /// reader.read_resolved_event()?; // <b>
883
    /// // The default prefix got overridden and new "b" prefix
884
    /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![
885
    ///     (PrefixDeclaration::Named(b"a"), Namespace(b"a2")),
886
    ///     (PrefixDeclaration::Default, Namespace(b"b1")),
887
    ///     (PrefixDeclaration::Named(b"b"), Namespace(b"b2"))
888
    /// ]);
889
    ///
890
    /// reader.read_resolved_event()?; // <c/>
891
    /// // Still the same
892
    /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![
893
    ///     (PrefixDeclaration::Named(b"a"), Namespace(b"a2")),
894
    ///     (PrefixDeclaration::Default, Namespace(b"b1")),
895
    ///     (PrefixDeclaration::Named(b"b"), Namespace(b"b2"))
896
    /// ]);
897
    ///
898
    /// reader.read_resolved_event()?; // </b>
899
    /// // Still the same
900
    /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![
901
    ///     (PrefixDeclaration::Named(b"a"), Namespace(b"a2")),
902
    ///     (PrefixDeclaration::Default, Namespace(b"b1")),
903
    ///     (PrefixDeclaration::Named(b"b"), Namespace(b"b2"))
904
    /// ]);
905
    ///
906
    /// reader.read_resolved_event()?; // <d/>
907
    /// // </b> got closed so back to the bindings declared on <a>
908
    /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![
909
    ///     (PrefixDeclaration::Default, Namespace(b"a1")),
910
    ///     (PrefixDeclaration::Named(b"a"), Namespace(b"a2"))
911
    /// ]);
912
    ///
913
    /// reader.read_resolved_event()?; // </a>
914
    /// // Still the same
915
    /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![
916
    ///     (PrefixDeclaration::Default, Namespace(b"a1")),
917
    ///     (PrefixDeclaration::Named(b"a"), Namespace(b"a2"))
918
    /// ]);
919
    ///
920
    /// reader.read_resolved_event()?; // </root>
921
    /// // <a> got closed
922
    /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![]);
923
    /// # quick_xml::Result::Ok(())
924
    /// ```
925
    #[inline]
926
0
    pub const fn bindings(&self) -> NamespaceBindingsIter<'_> {
927
0
        NamespaceBindingsIter {
928
0
            resolver: self,
929
0
            // We initialize the cursor to 2 to skip the two default namespaces xml: and xmlns:
930
0
            cursor: 2,
931
0
        }
932
0
    }
933
934
    /// Returns all the bindings on the specified level, including the default
935
    /// `xml` and `xmlns` bindings.
936
    ///
937
    /// # Parameters
938
    /// - `level`: the nesting level of an XML tag. The document without tags has
939
    ///   level 0, at which default bindings are declared. The root tag has level 1
940
    ///   and all other tags has levels > 1. If specify level more than [current], the
941
    ///   empty iterator is returned.
942
    ///
943
    /// # Examples
944
    ///
945
    /// This example shows what results the returned iterator would return on each
946
    /// level after reaning some events of a simple XML.
947
    ///
948
    /// ```
949
    /// # use pretty_assertions::assert_eq;
950
    /// use quick_xml::name::{Namespace, PrefixDeclaration};
951
    /// use quick_xml::NsReader;
952
    ///
953
    /// let src = "<root>
954
    ///   <a xmlns=\"a1\" xmlns:a=\"a2\">
955
    ///     <b xmlns=\"b1\" xmlns:b=\"b2\">
956
    ///       <c/>
957
    ///     </b>
958
    ///     <d/>
959
    ///   </a>
960
    /// </root>";
961
    /// let mut reader = NsReader::from_str(src);
962
    /// reader.config_mut().trim_text(true);
963
    /// reader.read_resolved_event()?; // <root>
964
    /// reader.read_resolved_event()?; // <a>
965
    /// reader.read_resolved_event()?; // <b>
966
    /// reader.read_resolved_event()?; // <c/>
967
    ///
968
    /// // Default bindings at the beginning
969
    /// assert_eq!(reader.resolver().bindings_of(0).collect::<Vec<_>>(), vec![
970
    ///     (PrefixDeclaration::Named(b"xml"), Namespace(b"http://www.w3.org/XML/1998/namespace")),
971
    ///     (PrefixDeclaration::Named(b"xmlns"), Namespace(b"http://www.w3.org/2000/xmlns/")),
972
    /// ]);
973
    ///
974
    /// // No bindings declared on root
975
    /// assert_eq!(reader.resolver().bindings_of(1).collect::<Vec<_>>(), vec![]);
976
    ///
977
    /// // Two bindings declared on "a"
978
    /// assert_eq!(reader.resolver().bindings_of(2).collect::<Vec<_>>(), vec![
979
    ///     (PrefixDeclaration::Default, Namespace(b"a1")),
980
    ///     (PrefixDeclaration::Named(b"a"), Namespace(b"a2")),
981
    /// ]);
982
    ///
983
    /// // Two bindings declared on "b"
984
    /// assert_eq!(reader.resolver().bindings_of(3).collect::<Vec<_>>(), vec![
985
    ///     (PrefixDeclaration::Default, Namespace(b"b1")),
986
    ///     (PrefixDeclaration::Named(b"b"), Namespace(b"b2")),
987
    /// ]);
988
    ///
989
    /// // No bindings declared on "c"
990
    /// assert_eq!(reader.resolver().bindings_of(4).collect::<Vec<_>>(), vec![]);
991
    ///
992
    /// // No bindings on non-existent level
993
    /// assert_eq!(reader.resolver().bindings_of(5).collect::<Vec<_>>(), vec![]);
994
    /// # quick_xml::Result::Ok(())
995
    /// ```
996
    ///
997
    /// [current]: Self::level
998
0
    pub const fn bindings_of(&self, level: u16) -> NamespaceBindingsOfLevelIter<'_> {
999
0
        NamespaceBindingsOfLevelIter {
1000
0
            resolver: self,
1001
0
            cursor: 0,
1002
0
            level,
1003
0
        }
1004
0
    }
1005
1006
    /// Returns the number of [`push`] calls that were not followed by [`pop`] calls.
1007
    ///
1008
    /// Due to use of `u16` for level number the number of nested tags in XML
1009
    /// are limited by [`u16::MAX`], but that is enough for any real application.
1010
    ///
1011
    /// # Example
1012
    ///
1013
    /// ```
1014
    /// # use pretty_assertions::assert_eq;
1015
    /// # use quick_xml::events::BytesStart;
1016
    /// # use quick_xml::name::{Namespace, NamespaceResolver, PrefixDeclaration, QName, ResolveResult};
1017
    /// #
1018
    /// let mut resolver = NamespaceResolver::default();
1019
    ///
1020
    /// assert_eq!(resolver.level(), 0);
1021
    ///
1022
    /// resolver.push(&BytesStart::new("tag"));
1023
    /// assert_eq!(resolver.level(), 1);
1024
    ///
1025
    /// resolver.pop();
1026
    /// assert_eq!(resolver.level(), 0);
1027
    ///
1028
    /// // pop from empty resolver does nothing
1029
    /// resolver.pop();
1030
    /// assert_eq!(resolver.level(), 0);
1031
    /// ```
1032
    ///
1033
    /// [`push`]: Self::push
1034
    /// [`pop`]: Self::pop
1035
0
    pub const fn level(&self) -> u16 {
1036
0
        self.nesting_level
1037
0
    }
1038
}
1039
1040
////////////////////////////////////////////////////////////////////////////////////////////////////
1041
1042
/// Iterator on the current declared namespace bindings. Returns pairs of the _(prefix, namespace)_.
1043
///
1044
/// See [`NamespaceResolver::bindings`] for documentation.
1045
#[derive(Debug, Clone)]
1046
pub struct NamespaceBindingsIter<'a> {
1047
    resolver: &'a NamespaceResolver,
1048
    cursor: usize,
1049
}
1050
1051
impl<'a> Iterator for NamespaceBindingsIter<'a> {
1052
    type Item = (PrefixDeclaration<'a>, Namespace<'a>);
1053
1054
0
    fn next(&mut self) -> Option<(PrefixDeclaration<'a>, Namespace<'a>)> {
1055
0
        while let Some(binding) = self.resolver.bindings.get(self.cursor) {
1056
0
            self.cursor += 1; // We increment for next read
1057
1058
            // We check if the key has not been overridden by having a look
1059
            // at the namespaces declared after in the array
1060
0
            let prefix = binding.prefix(&self.resolver.buffer);
1061
0
            if self.resolver.bindings[self.cursor..]
1062
0
                .iter()
1063
0
                .any(|ne| prefix == ne.prefix(&self.resolver.buffer))
1064
            {
1065
0
                continue; // Overridden
1066
0
            }
1067
0
            if let ResolveResult::Bound(namespace) = binding.namespace(&self.resolver.buffer) {
1068
0
                let prefix = match prefix {
1069
0
                    Some(Prefix(prefix)) => PrefixDeclaration::Named(prefix),
1070
0
                    None => PrefixDeclaration::Default,
1071
                };
1072
0
                return Some((prefix, namespace));
1073
0
            }
1074
        }
1075
0
        None // We have exhausted the array
1076
0
    }
1077
1078
0
    fn size_hint(&self) -> (usize, Option<usize>) {
1079
        // Real count could be less if some namespaces was overridden
1080
0
        (0, Some(self.resolver.bindings.len() - self.cursor))
1081
0
    }
1082
}
1083
1084
impl<'a> FusedIterator for NamespaceBindingsIter<'a> {}
1085
1086
/// The previous name for [`NamespaceBindingsIter`].
1087
pub type PrefixIter<'a> = NamespaceBindingsIter<'a>;
1088
1089
/// Iterator on the declared namespace bindings on specified level. Returns pairs of the _(prefix, namespace)_.
1090
///
1091
/// See [`NamespaceResolver::bindings_of`] for documentation.
1092
#[derive(Debug, Clone)]
1093
pub struct NamespaceBindingsOfLevelIter<'a> {
1094
    resolver: &'a NamespaceResolver,
1095
    cursor: usize,
1096
    level: u16,
1097
}
1098
1099
impl<'a> Iterator for NamespaceBindingsOfLevelIter<'a> {
1100
    type Item = (PrefixDeclaration<'a>, Namespace<'a>);
1101
1102
0
    fn next(&mut self) -> Option<(PrefixDeclaration<'a>, Namespace<'a>)> {
1103
0
        while let Some(binding) = self.resolver.bindings.get(self.cursor) {
1104
0
            self.cursor += 1; // We increment for next read
1105
0
            if binding.level < self.level {
1106
0
                continue;
1107
0
            }
1108
0
            if binding.level > self.level {
1109
0
                break;
1110
0
            }
1111
1112
0
            if let ResolveResult::Bound(namespace) = binding.namespace(&self.resolver.buffer) {
1113
0
                let prefix = match binding.prefix(&self.resolver.buffer) {
1114
0
                    Some(Prefix(prefix)) => PrefixDeclaration::Named(prefix),
1115
0
                    None => PrefixDeclaration::Default,
1116
                };
1117
0
                return Some((prefix, namespace));
1118
0
            }
1119
        }
1120
0
        None // We have exhausted the array
1121
0
    }
1122
1123
0
    fn size_hint(&self) -> (usize, Option<usize>) {
1124
        // Real count could be less
1125
0
        (0, Some(self.resolver.bindings.len() - self.cursor))
1126
0
    }
1127
}
1128
1129
impl<'a> FusedIterator for NamespaceBindingsOfLevelIter<'a> {}
1130
1131
////////////////////////////////////////////////////////////////////////////////////////////////////
1132
1133
#[cfg(test)]
1134
mod namespaces {
1135
    use super::*;
1136
    use pretty_assertions::assert_eq;
1137
    use ResolveResult::*;
1138
1139
    /// Unprefixed attribute names (resolved with `false` flag) never have a namespace
1140
    /// according to <https://www.w3.org/TR/xml-names11/#defaulting>:
1141
    ///
1142
    /// > A default namespace declaration applies to all unprefixed element names
1143
    /// > within its scope. Default namespace declarations do not apply directly
1144
    /// > to attribute names; the interpretation of unprefixed attributes is
1145
    /// > determined by the element on which they appear.
1146
    mod unprefixed {
1147
        use super::*;
1148
        use pretty_assertions::assert_eq;
1149
1150
        /// Basic tests that checks that basic resolver functionality is working
1151
        #[test]
1152
        fn basic() {
1153
            let name = QName(b"simple");
1154
            let ns = Namespace(b"default");
1155
1156
            let mut resolver = NamespaceResolver::default();
1157
            let s = resolver.buffer.len();
1158
1159
            resolver
1160
                .push(&BytesStart::from_content(" xmlns='default'", 0))
1161
                .unwrap();
1162
            assert_eq!(&resolver.buffer[s..], b"default");
1163
1164
            // Check that tags without namespaces does not change result
1165
            resolver.push(&BytesStart::from_content("", 0)).unwrap();
1166
            assert_eq!(&resolver.buffer[s..], b"default");
1167
            resolver.pop();
1168
1169
            assert_eq!(&resolver.buffer[s..], b"default");
1170
            assert_eq!(
1171
                resolver.resolve(name, true),
1172
                (Bound(ns), LocalName(b"simple"))
1173
            );
1174
            assert_eq!(
1175
                resolver.resolve(name, false),
1176
                (Unbound, LocalName(b"simple"))
1177
            );
1178
        }
1179
1180
        /// Test adding a second level of namespaces, which replaces the previous binding
1181
        #[test]
1182
        fn override_namespace() {
1183
            let name = QName(b"simple");
1184
            let old_ns = Namespace(b"old");
1185
            let new_ns = Namespace(b"new");
1186
1187
            let mut resolver = NamespaceResolver::default();
1188
            let s = resolver.buffer.len();
1189
1190
            resolver
1191
                .push(&BytesStart::from_content(" xmlns='old'", 0))
1192
                .unwrap();
1193
            resolver
1194
                .push(&BytesStart::from_content(" xmlns='new'", 0))
1195
                .unwrap();
1196
1197
            assert_eq!(&resolver.buffer[s..], b"oldnew");
1198
            assert_eq!(
1199
                resolver.resolve(name, true),
1200
                (Bound(new_ns), LocalName(b"simple"))
1201
            );
1202
            assert_eq!(
1203
                resolver.resolve(name, false),
1204
                (Unbound, LocalName(b"simple"))
1205
            );
1206
1207
            resolver.pop();
1208
            assert_eq!(&resolver.buffer[s..], b"old");
1209
            assert_eq!(
1210
                resolver.resolve(name, true),
1211
                (Bound(old_ns), LocalName(b"simple"))
1212
            );
1213
            assert_eq!(
1214
                resolver.resolve(name, false),
1215
                (Unbound, LocalName(b"simple"))
1216
            );
1217
        }
1218
1219
        /// Test adding a second level of namespaces, which reset the previous binding
1220
        /// to not bound state by specifying an empty namespace name.
1221
        ///
1222
        /// See <https://www.w3.org/TR/xml-names11/#scoping>
1223
        #[test]
1224
        fn reset() {
1225
            let name = QName(b"simple");
1226
            let old_ns = Namespace(b"old");
1227
1228
            let mut resolver = NamespaceResolver::default();
1229
            let s = resolver.buffer.len();
1230
1231
            resolver
1232
                .push(&BytesStart::from_content(" xmlns='old'", 0))
1233
                .unwrap();
1234
            resolver
1235
                .push(&BytesStart::from_content(" xmlns=''", 0))
1236
                .unwrap();
1237
1238
            assert_eq!(&resolver.buffer[s..], b"old");
1239
            assert_eq!(
1240
                resolver.resolve(name, true),
1241
                (Unbound, LocalName(b"simple"))
1242
            );
1243
            assert_eq!(
1244
                resolver.resolve(name, false),
1245
                (Unbound, LocalName(b"simple"))
1246
            );
1247
1248
            resolver.pop();
1249
            assert_eq!(&resolver.buffer[s..], b"old");
1250
            assert_eq!(
1251
                resolver.resolve(name, true),
1252
                (Bound(old_ns), LocalName(b"simple"))
1253
            );
1254
            assert_eq!(
1255
                resolver.resolve(name, false),
1256
                (Unbound, LocalName(b"simple"))
1257
            );
1258
        }
1259
    }
1260
1261
    mod declared_prefix {
1262
        use super::*;
1263
        use pretty_assertions::assert_eq;
1264
1265
        /// Basic tests that checks that basic resolver functionality is working
1266
        #[test]
1267
        fn basic() {
1268
            let name = QName(b"p:with-declared-prefix");
1269
            let ns = Namespace(b"default");
1270
1271
            let mut resolver = NamespaceResolver::default();
1272
            let s = resolver.buffer.len();
1273
1274
            resolver
1275
                .push(&BytesStart::from_content(" xmlns:p='default'", 0))
1276
                .unwrap();
1277
            assert_eq!(&resolver.buffer[s..], b"pdefault");
1278
1279
            // Check that tags without namespaces does not change result
1280
            resolver.push(&BytesStart::from_content("", 0)).unwrap();
1281
            assert_eq!(&resolver.buffer[s..], b"pdefault");
1282
            resolver.pop();
1283
1284
            assert_eq!(&resolver.buffer[s..], b"pdefault");
1285
            assert_eq!(
1286
                resolver.resolve(name, true),
1287
                (Bound(ns), LocalName(b"with-declared-prefix"))
1288
            );
1289
            assert_eq!(
1290
                resolver.resolve(name, false),
1291
                (Bound(ns), LocalName(b"with-declared-prefix"))
1292
            );
1293
        }
1294
1295
        /// Test adding a second level of namespaces, which replaces the previous binding
1296
        #[test]
1297
        fn override_namespace() {
1298
            let name = QName(b"p:with-declared-prefix");
1299
            let old_ns = Namespace(b"old");
1300
            let new_ns = Namespace(b"new");
1301
1302
            let mut resolver = NamespaceResolver::default();
1303
            let s = resolver.buffer.len();
1304
1305
            resolver
1306
                .push(&BytesStart::from_content(" xmlns:p='old'", 0))
1307
                .unwrap();
1308
            resolver
1309
                .push(&BytesStart::from_content(" xmlns:p='new'", 0))
1310
                .unwrap();
1311
1312
            assert_eq!(&resolver.buffer[s..], b"poldpnew");
1313
            assert_eq!(
1314
                resolver.resolve(name, true),
1315
                (Bound(new_ns), LocalName(b"with-declared-prefix"))
1316
            );
1317
            assert_eq!(
1318
                resolver.resolve(name, false),
1319
                (Bound(new_ns), LocalName(b"with-declared-prefix"))
1320
            );
1321
1322
            resolver.pop();
1323
            assert_eq!(&resolver.buffer[s..], b"pold");
1324
            assert_eq!(
1325
                resolver.resolve(name, true),
1326
                (Bound(old_ns), LocalName(b"with-declared-prefix"))
1327
            );
1328
            assert_eq!(
1329
                resolver.resolve(name, false),
1330
                (Bound(old_ns), LocalName(b"with-declared-prefix"))
1331
            );
1332
        }
1333
1334
        /// Test adding a second level of namespaces, which reset the previous binding
1335
        /// to not bound state by specifying an empty namespace name.
1336
        ///
1337
        /// See <https://www.w3.org/TR/xml-names11/#scoping>
1338
        #[test]
1339
        fn reset() {
1340
            let name = QName(b"p:with-declared-prefix");
1341
            let old_ns = Namespace(b"old");
1342
1343
            let mut resolver = NamespaceResolver::default();
1344
            let s = resolver.buffer.len();
1345
1346
            resolver
1347
                .push(&BytesStart::from_content(" xmlns:p='old'", 0))
1348
                .unwrap();
1349
            resolver
1350
                .push(&BytesStart::from_content(" xmlns:p=''", 0))
1351
                .unwrap();
1352
1353
            assert_eq!(&resolver.buffer[s..], b"poldp");
1354
            assert_eq!(
1355
                resolver.resolve(name, true),
1356
                (Unknown(b"p".to_vec()), LocalName(b"with-declared-prefix"))
1357
            );
1358
            assert_eq!(
1359
                resolver.resolve(name, false),
1360
                (Unknown(b"p".to_vec()), LocalName(b"with-declared-prefix"))
1361
            );
1362
1363
            resolver.pop();
1364
            assert_eq!(&resolver.buffer[s..], b"pold");
1365
            assert_eq!(
1366
                resolver.resolve(name, true),
1367
                (Bound(old_ns), LocalName(b"with-declared-prefix"))
1368
            );
1369
            assert_eq!(
1370
                resolver.resolve(name, false),
1371
                (Bound(old_ns), LocalName(b"with-declared-prefix"))
1372
            );
1373
        }
1374
    }
1375
1376
    /// Tests for `xml` and `xmlns` built-in prefixes.
1377
    ///
1378
    /// See <https://www.w3.org/TR/xml-names11/#xmlReserved>
1379
    mod builtin_prefixes {
1380
        use super::*;
1381
1382
        mod xml {
1383
            use super::*;
1384
            use pretty_assertions::assert_eq;
1385
1386
            /// `xml` prefix are always defined, it is not required to define it explicitly.
1387
            #[test]
1388
            fn undeclared() {
1389
                let name = QName(b"xml:random");
1390
                let namespace = RESERVED_NAMESPACE_XML.1;
1391
1392
                let resolver = NamespaceResolver::default();
1393
1394
                assert_eq!(
1395
                    resolver.resolve(name, true),
1396
                    (Bound(namespace), LocalName(b"random"))
1397
                );
1398
1399
                assert_eq!(
1400
                    resolver.resolve(name, false),
1401
                    (Bound(namespace), LocalName(b"random"))
1402
                );
1403
            }
1404
1405
            /// `xml` prefix can be declared but it must be bound to the value
1406
            /// `http://www.w3.org/XML/1998/namespace`
1407
            #[test]
1408
            fn rebound_to_correct_ns() {
1409
                let mut resolver = NamespaceResolver::default();
1410
                let s = resolver.buffer.len();
1411
                resolver.push(
1412
                    &BytesStart::from_content(
1413
                        " xmlns:xml='http://www.w3.org/XML/1998/namespace'",
1414
                        0,
1415
                    ),
1416
                ).expect("`xml` prefix should be possible to bound to `http://www.w3.org/XML/1998/namespace`");
1417
                assert_eq!(&resolver.buffer[s..], b"");
1418
            }
1419
1420
            /// `xml` prefix cannot be re-declared to another namespace
1421
            #[test]
1422
            fn rebound_to_incorrect_ns() {
1423
                let mut resolver = NamespaceResolver::default();
1424
                let s = resolver.buffer.len();
1425
                assert_eq!(
1426
                    resolver.push(&BytesStart::from_content(
1427
                        " xmlns:xml='not_correct_namespace'",
1428
                        0,
1429
                    )),
1430
                    Err(NamespaceError::InvalidXmlPrefixBind(
1431
                        b"not_correct_namespace".to_vec()
1432
                    )),
1433
                );
1434
                assert_eq!(&resolver.buffer[s..], b"");
1435
            }
1436
1437
            /// `xml` prefix cannot be unbound
1438
            #[test]
1439
            fn unbound() {
1440
                let mut resolver = NamespaceResolver::default();
1441
                let s = resolver.buffer.len();
1442
                assert_eq!(
1443
                    resolver.push(&BytesStart::from_content(" xmlns:xml=''", 0)),
1444
                    Err(NamespaceError::InvalidXmlPrefixBind(b"".to_vec())),
1445
                );
1446
                assert_eq!(&resolver.buffer[s..], b"");
1447
            }
1448
1449
            /// Other prefix cannot be bound to `xml` namespace
1450
            #[test]
1451
            fn other_prefix_bound_to_xml_namespace() {
1452
                let mut resolver = NamespaceResolver::default();
1453
                let s = resolver.buffer.len();
1454
                assert_eq!(
1455
                    resolver.push(&BytesStart::from_content(
1456
                        " xmlns:not_xml='http://www.w3.org/XML/1998/namespace'",
1457
                        0,
1458
                    )),
1459
                    Err(NamespaceError::InvalidPrefixForXml(b"not_xml".to_vec())),
1460
                );
1461
                assert_eq!(&resolver.buffer[s..], b"");
1462
            }
1463
        }
1464
1465
        mod xmlns {
1466
            use super::*;
1467
            use pretty_assertions::assert_eq;
1468
1469
            /// `xmlns` prefix are always defined, it is forbidden to define it explicitly
1470
            #[test]
1471
            fn undeclared() {
1472
                let name = QName(b"xmlns:random");
1473
                let namespace = RESERVED_NAMESPACE_XMLNS.1;
1474
1475
                let resolver = NamespaceResolver::default();
1476
1477
                assert_eq!(
1478
                    resolver.resolve(name, true),
1479
                    (Bound(namespace), LocalName(b"random"))
1480
                );
1481
1482
                assert_eq!(
1483
                    resolver.resolve(name, false),
1484
                    (Bound(namespace), LocalName(b"random"))
1485
                );
1486
            }
1487
1488
            /// `xmlns` prefix cannot be re-declared event to its own namespace
1489
            #[test]
1490
            fn rebound_to_correct_ns() {
1491
                let mut resolver = NamespaceResolver::default();
1492
                let s = resolver.buffer.len();
1493
                assert_eq!(
1494
                    resolver.push(&BytesStart::from_content(
1495
                        " xmlns:xmlns='http://www.w3.org/2000/xmlns/'",
1496
                        0,
1497
                    )),
1498
                    Err(NamespaceError::InvalidXmlnsPrefixBind(
1499
                        b"http://www.w3.org/2000/xmlns/".to_vec()
1500
                    )),
1501
                );
1502
                assert_eq!(&resolver.buffer[s..], b"");
1503
            }
1504
1505
            /// `xmlns` prefix cannot be re-declared
1506
            #[test]
1507
            fn rebound_to_incorrect_ns() {
1508
                let mut resolver = NamespaceResolver::default();
1509
                let s = resolver.buffer.len();
1510
                assert_eq!(
1511
                    resolver.push(&BytesStart::from_content(
1512
                        " xmlns:xmlns='not_correct_namespace'",
1513
                        0,
1514
                    )),
1515
                    Err(NamespaceError::InvalidXmlnsPrefixBind(
1516
                        b"not_correct_namespace".to_vec()
1517
                    )),
1518
                );
1519
                assert_eq!(&resolver.buffer[s..], b"");
1520
            }
1521
1522
            /// `xmlns` prefix cannot be unbound
1523
            #[test]
1524
            fn unbound() {
1525
                let mut resolver = NamespaceResolver::default();
1526
                let s = resolver.buffer.len();
1527
                assert_eq!(
1528
                    resolver.push(&BytesStart::from_content(" xmlns:xmlns=''", 0)),
1529
                    Err(NamespaceError::InvalidXmlnsPrefixBind(b"".to_vec())),
1530
                );
1531
                assert_eq!(&resolver.buffer[s..], b"");
1532
            }
1533
1534
            /// Other prefix cannot be bound to `xmlns` namespace
1535
            #[test]
1536
            fn other_prefix_bound_to_xmlns_namespace() {
1537
                let mut resolver = NamespaceResolver::default();
1538
                let s = resolver.buffer.len();
1539
                assert_eq!(
1540
                    resolver.push(&BytesStart::from_content(
1541
                        " xmlns:not_xmlns='http://www.w3.org/2000/xmlns/'",
1542
                        0,
1543
                    )),
1544
                    Err(NamespaceError::InvalidPrefixForXmlns(b"not_xmlns".to_vec())),
1545
                );
1546
                assert_eq!(&resolver.buffer[s..], b"");
1547
            }
1548
        }
1549
    }
1550
1551
    #[test]
1552
    fn undeclared_prefix() {
1553
        let name = QName(b"unknown:prefix");
1554
1555
        let resolver = NamespaceResolver::default();
1556
1557
        assert_eq!(
1558
            resolver.buffer,
1559
            b"xmlhttp://www.w3.org/XML/1998/namespacexmlnshttp://www.w3.org/2000/xmlns/"
1560
        );
1561
        assert_eq!(
1562
            resolver.resolve(name, true),
1563
            (Unknown(b"unknown".to_vec()), LocalName(b"prefix"))
1564
        );
1565
        assert_eq!(
1566
            resolver.resolve(name, false),
1567
            (Unknown(b"unknown".to_vec()), LocalName(b"prefix"))
1568
        );
1569
    }
1570
1571
    /// Checks how the QName is decomposed to a prefix and a local name
1572
    #[test]
1573
    fn prefix_and_local_name() {
1574
        let name = QName(b"foo:bus");
1575
        assert_eq!(name.prefix(), Some(Prefix(b"foo")));
1576
        assert_eq!(name.local_name(), LocalName(b"bus"));
1577
        assert_eq!(name.decompose(), (LocalName(b"bus"), Some(Prefix(b"foo"))));
1578
1579
        let name = QName(b"foo:");
1580
        assert_eq!(name.prefix(), Some(Prefix(b"foo")));
1581
        assert_eq!(name.local_name(), LocalName(b""));
1582
        assert_eq!(name.decompose(), (LocalName(b""), Some(Prefix(b"foo"))));
1583
1584
        let name = QName(b":foo");
1585
        assert_eq!(name.prefix(), Some(Prefix(b"")));
1586
        assert_eq!(name.local_name(), LocalName(b"foo"));
1587
        assert_eq!(name.decompose(), (LocalName(b"foo"), Some(Prefix(b""))));
1588
1589
        let name = QName(b"foo:bus:baz");
1590
        assert_eq!(name.prefix(), Some(Prefix(b"foo")));
1591
        assert_eq!(name.local_name(), LocalName(b"bus:baz"));
1592
        assert_eq!(
1593
            name.decompose(),
1594
            (LocalName(b"bus:baz"), Some(Prefix(b"foo")))
1595
        );
1596
    }
1597
}