Skip to main content

quick_xml/
name.rs

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