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;
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    fn prefix<'b>(&self, ns_buffer: &'b [u8]) -> Option<Prefix<'b>> {
457        if self.prefix_len == 0 {
458            None
459        } else {
460            Some(Prefix(&ns_buffer[self.start..self.start + self.prefix_len]))
461        }
462    }
463
464    /// Gets the namespace name (the URI) slice out of namespace buffer
465    ///
466    /// Returns `None` if namespace for this prefix was explicitly removed from
467    /// scope, using `xmlns[:prefix]=""`
468    #[inline]
469    fn namespace<'ns>(&self, buffer: &'ns [u8]) -> ResolveResult<'ns> {
470        if self.value_len == 0 {
471            ResolveResult::Unbound
472        } else {
473            let start = self.start + self.prefix_len;
474            ResolveResult::Bound(Namespace(&buffer[start..start + self.value_len]))
475        }
476    }
477}
478
479/// A storage for currently defined namespace bindings, which is used to resolve
480/// prefixes into namespaces.
481///
482/// Holds all internal logic to push/pop namespaces with their levels.
483#[derive(Debug, Clone)]
484pub struct NamespaceResolver {
485    /// Buffer that contains names of namespace prefixes (the part between `xmlns:`
486    /// and an `=`) and namespace values.
487    buffer: Vec<u8>,
488    /// A stack of namespace bindings to prefixes that currently in scope
489    bindings: Vec<NamespaceBinding>,
490    /// The number of open tags at the moment. We need to keep track of this to know which namespace
491    /// declarations to remove when we encounter an `End` event.
492    nesting_level: u16,
493}
494
495/// That constant define the one of [reserved namespaces] for the xml standard.
496///
497/// The prefix `xml` is by definition bound to the namespace name
498/// `http://www.w3.org/XML/1998/namespace`. It may, but need not, be declared, and must not be
499/// undeclared or bound to any other namespace name. Other prefixes must not be bound to this
500/// namespace name, and it must not be declared as the default namespace.
501///
502/// [reserved namespaces]: https://www.w3.org/TR/xml-names11/#xmlReserved
503const RESERVED_NAMESPACE_XML: (Prefix, Namespace) = (
504    Prefix(b"xml"),
505    Namespace(b"http://www.w3.org/XML/1998/namespace"),
506);
507/// That constant define the one of [reserved namespaces] for the xml standard.
508///
509/// The prefix `xmlns` is used only to declare namespace bindings and is by definition bound
510/// to the namespace name `http://www.w3.org/2000/xmlns/`. It must not be declared or
511/// undeclared. Other prefixes must not be bound to this namespace name, and it must not be
512/// declared as the default namespace. Element names must not have the prefix `xmlns`.
513///
514/// [reserved namespaces]: https://www.w3.org/TR/xml-names11/#xmlReserved
515const RESERVED_NAMESPACE_XMLNS: (Prefix, Namespace) = (
516    Prefix(b"xmlns"),
517    Namespace(b"http://www.w3.org/2000/xmlns/"),
518);
519
520impl Default for NamespaceResolver {
521    fn default() -> Self {
522        let mut buffer = Vec::new();
523        let mut bindings = Vec::new();
524        for ent in &[RESERVED_NAMESPACE_XML, RESERVED_NAMESPACE_XMLNS] {
525            let prefix = ent.0.into_inner();
526            let uri = ent.1.into_inner();
527            bindings.push(NamespaceBinding {
528                start: buffer.len(),
529                prefix_len: prefix.len(),
530                value_len: uri.len(),
531                level: 0,
532            });
533            buffer.extend(prefix);
534            buffer.extend(uri);
535        }
536
537        Self {
538            buffer,
539            bindings,
540            nesting_level: 0,
541        }
542    }
543}
544
545impl NamespaceResolver {
546    /// Adds new binding of prefix to namespace, returns the result of operation.
547    ///
548    /// Binding will be added on current nesting level and will be removed, when
549    /// level will be [popped out].
550    ///
551    /// The operation may fail if you try to (re-)declare reserved prefixes `xml` and `xmlns`.
552    ///
553    /// Note, that method does not check if namespace was already added on that level.
554    /// Use `resolver.bindings_of(resolver.level()).any()` if you want to check that.
555    /// New definition will be added and replace the old.
556    ///
557    /// Implementation detail: memory occupied by old binding of that level still will be used.
558    ///
559    /// ```
560    /// # use pretty_assertions::assert_eq;
561    /// # use quick_xml::name::{Namespace, NamespaceResolver, PrefixDeclaration, QName, ResolveResult};
562    /// #
563    /// let mut resolver = NamespaceResolver::default();
564    /// // names without prefix are unbound by default
565    /// assert_eq!(
566    ///     resolver.resolve_element(QName(b"name")).0,
567    ///     ResolveResult::Unbound,
568    /// );
569    /// // names with undeclared prefix are unknown
570    /// assert_eq!(
571    ///     resolver.resolve_element(QName(b"ns:name")).0,
572    ///     ResolveResult::Unknown(b"ns".to_vec()),
573    /// );
574    ///
575    /// resolver.add(PrefixDeclaration::Default, Namespace(b"example.com"));
576    /// resolver.add(PrefixDeclaration::Named(b"ns"), Namespace(b"my:namespace"));
577    ///
578    /// assert_eq!(
579    ///     resolver.resolve_element(QName(b"name")).0,
580    ///     ResolveResult::Bound(Namespace(b"example.com")),
581    /// );
582    /// assert_eq!(
583    ///     resolver.resolve_element(QName(b"ns:name")).0,
584    ///     ResolveResult::Bound(Namespace(b"my:namespace")),
585    /// );
586    ///
587    /// // adding empty namespace clears the binding
588    /// resolver.add(PrefixDeclaration::Default, Namespace(b""));
589    /// resolver.add(PrefixDeclaration::Named(b"ns"), Namespace(b""));
590    ///
591    /// assert_eq!(
592    ///     resolver.resolve_element(QName(b"name")).0,
593    ///     ResolveResult::Unbound,
594    /// );
595    /// assert_eq!(
596    ///     resolver.resolve_element(QName(b"ns:name")).0,
597    ///     ResolveResult::Unknown(b"ns".to_vec()),
598    /// );
599    /// ```
600    /// [popped out]: Self::pop
601    pub fn add(
602        &mut self,
603        prefix: PrefixDeclaration,
604        namespace: Namespace,
605    ) -> Result<(), NamespaceError> {
606        let level = self.nesting_level;
607        match prefix {
608            PrefixDeclaration::Default => {
609                let start = self.buffer.len();
610                self.buffer.extend_from_slice(namespace.0);
611                self.bindings.push(NamespaceBinding {
612                    start,
613                    prefix_len: 0,
614                    value_len: namespace.0.len(),
615                    level,
616                });
617            }
618            PrefixDeclaration::Named(b"xml") => {
619                if namespace != RESERVED_NAMESPACE_XML.1 {
620                    // error, `xml` prefix explicitly set to different value
621                    return Err(NamespaceError::InvalidXmlPrefixBind(namespace.0.to_vec()));
622                }
623                // don't add another NamespaceEntry for the `xml` namespace prefix
624            }
625            PrefixDeclaration::Named(b"xmlns") => {
626                // error, `xmlns` prefix explicitly set
627                return Err(NamespaceError::InvalidXmlnsPrefixBind(namespace.0.to_vec()));
628            }
629            PrefixDeclaration::Named(prefix) => {
630                // error, non-`xml` prefix set to xml uri
631                if namespace == RESERVED_NAMESPACE_XML.1 {
632                    return Err(NamespaceError::InvalidPrefixForXml(prefix.to_vec()));
633                } else
634                // error, non-`xmlns` prefix set to xmlns uri
635                if namespace == RESERVED_NAMESPACE_XMLNS.1 {
636                    return Err(NamespaceError::InvalidPrefixForXmlns(prefix.to_vec()));
637                }
638
639                let start = self.buffer.len();
640                self.buffer.extend_from_slice(prefix);
641                self.buffer.extend_from_slice(namespace.0);
642                self.bindings.push(NamespaceBinding {
643                    start,
644                    prefix_len: prefix.len(),
645                    value_len: namespace.0.len(),
646                    level,
647                });
648            }
649        }
650        Ok(())
651    }
652
653    /// Begins a new scope and add to it all [namespace bindings] that found in
654    /// the specified start element.
655    ///
656    /// [namespace bindings]: https://www.w3.org/TR/xml-names11/#dt-NSDecl
657    pub fn push(&mut self, start: &BytesStart) -> Result<(), NamespaceError> {
658        self.nesting_level += 1;
659        // adds new namespaces for attributes starting with 'xmlns:' and for the 'xmlns'
660        // (default namespace) attribute.
661        for a in start.attributes().with_checks(false) {
662            if let Ok(Attribute { key: k, value: v }) = a {
663                if let Some(prefix) = k.as_namespace_binding() {
664                    self.add(prefix, Namespace(&v))?;
665                }
666            } else {
667                break;
668            }
669        }
670        Ok(())
671    }
672
673    /// Ends a top-most scope by popping all [namespace bindings], that was added by
674    /// last call to [`Self::push()`] and [`Self::add()`].
675    ///
676    /// [namespace bindings]: https://www.w3.org/TR/xml-names11/#dt-NSDecl
677    pub fn pop(&mut self) {
678        self.nesting_level = self.nesting_level.saturating_sub(1);
679        let current_level = self.nesting_level;
680        // from the back (most deeply nested scope), look for the first scope that is still valid
681        match self.bindings.iter().rposition(|n| n.level <= current_level) {
682            // none of the namespaces are valid, remove all of them
683            None => {
684                self.buffer.clear();
685                self.bindings.clear();
686            }
687            // drop all namespaces past the last valid namespace
688            Some(last_valid_pos) => {
689                if let Some(len) = self.bindings.get(last_valid_pos + 1).map(|n| n.start) {
690                    self.buffer.truncate(len);
691                    self.bindings.truncate(last_valid_pos + 1);
692                }
693            }
694        }
695    }
696
697    /// Resolves a potentially qualified **element name** or **attribute name**
698    /// into _(namespace name, local name)_.
699    ///
700    /// _Qualified_ names have the form `local-name` or `prefix:local-name` where the `prefix`
701    /// is defined on any containing XML element via `xmlns:prefix="the:namespace:uri"`.
702    /// The namespace prefix can be defined on the same element as the name in question.
703    ///
704    /// The method returns following results depending on the `name` shape, `attribute` flag
705    /// and the presence of the default namespace on element or any of its parents:
706    ///
707    /// |use_default|`xmlns="..."`|QName              |ResolveResult          |LocalName
708    /// |-----------|-------------|-------------------|-----------------------|------------
709    /// |`false`    |_(any)_      |`local-name`       |[`Unbound`]            |`local-name`
710    /// |`false`    |_(any)_      |`prefix:local-name`|[`Bound`] / [`Unknown`]|`local-name`
711    /// |`true`     |Not defined  |`local-name`       |[`Unbound`]            |`local-name`
712    /// |`true`     |Defined      |`local-name`       |[`Bound`] (to `xmlns`) |`local-name`
713    /// |`true`     |_(any)_      |`prefix:local-name`|[`Bound`] / [`Unknown`]|`local-name`
714    ///
715    /// # Parameters
716    /// - `name`: probably qualified name to resolve;
717    /// - `use_default`: whether to try to translate `None` prefix to the currently default namespace
718    ///   (bound using `xmlns="default namespace"`) or return [`ResolveResult::Unbound`].
719    ///   For attribute names this should be set to `false` and for element names to `true`.
720    ///
721    /// # Lifetimes
722    ///
723    /// - `'n`: lifetime of a name. Returned local name will be bound to the same
724    ///   lifetime as the name in question.
725    /// - returned namespace name will be bound to the resolver itself
726    ///
727    /// [`Bound`]: ResolveResult::Bound
728    /// [`Unbound`]: ResolveResult::Unbound
729    /// [`Unknown`]: ResolveResult::Unknown
730    #[inline]
731    pub fn resolve<'n>(
732        &self,
733        name: QName<'n>,
734        use_default: bool,
735    ) -> (ResolveResult<'_>, LocalName<'n>) {
736        let (local_name, prefix) = name.decompose();
737        (self.resolve_prefix(prefix, use_default), local_name)
738    }
739
740    /// Convenient method to call `resolve(name, true)`. May be used to clearly
741    /// express that we want to resolve an element name, and not an attribute name.
742    #[inline]
743    pub fn resolve_element<'n>(&self, name: QName<'n>) -> (ResolveResult<'_>, LocalName<'n>) {
744        self.resolve(name, true)
745    }
746
747    /// Convenient method to call `resolve(name, false)`. May be used to clearly
748    /// express that we want to resolve an attribute name, and not an element name.
749    #[inline]
750    pub fn resolve_attribute<'n>(&self, name: QName<'n>) -> (ResolveResult<'_>, LocalName<'n>) {
751        self.resolve(name, false)
752    }
753
754    /// Finds a [namespace name] for a given event, if applicable.
755    ///
756    /// Namespace is resolved only for [`Start`], [`Empty`] and [`End`] events.
757    /// For all other events the concept of namespace is not defined, so
758    /// a [`ResolveResult::Unbound`] is returned.
759    ///
760    /// # Examples
761    ///
762    /// ```
763    /// # use pretty_assertions::assert_eq;
764    /// use quick_xml::events::Event;
765    /// use quick_xml::name::{Namespace, QName, ResolveResult::*};
766    /// use quick_xml::reader::NsReader;
767    ///
768    /// let mut reader = NsReader::from_str(r#"
769    ///     <x:tag1 xmlns:x="www.xxxx" xmlns:y="www.yyyy" att1 = "test">
770    ///        <y:tag2><!--Test comment-->Test</y:tag2>
771    ///        <y:tag2>Test 2</y:tag2>
772    ///     </x:tag1>
773    /// "#);
774    /// reader.config_mut().trim_text(true);
775    ///
776    /// let mut count = 0;
777    /// let mut txt = Vec::new();
778    /// loop {
779    ///     let event = reader.read_event().unwrap();
780    ///     match reader.resolver().resolve_event(event) {
781    ///         (Bound(Namespace(b"www.xxxx")), Event::Start(e)) => {
782    ///             count += 1;
783    ///             assert_eq!(e.local_name(), QName(b"tag1").into());
784    ///         }
785    ///         (Bound(Namespace(b"www.yyyy")), Event::Start(e)) => {
786    ///             count += 1;
787    ///             assert_eq!(e.local_name(), QName(b"tag2").into());
788    ///         }
789    ///         (_, Event::Start(_)) => unreachable!(),
790    ///
791    ///         (_, Event::Text(e)) => {
792    ///             txt.push(e.decode().unwrap().into_owned())
793    ///         }
794    ///         (_, Event::Eof) => break,
795    ///         _ => (),
796    ///     }
797    /// }
798    /// assert_eq!(count, 3);
799    /// assert_eq!(txt, vec!["Test".to_string(), "Test 2".to_string()]);
800    /// ```
801    ///
802    /// [namespace name]: https://www.w3.org/TR/xml-names11/#dt-NSName
803    /// [`Empty`]: Event::Empty
804    /// [`Start`]: Event::Start
805    /// [`End`]: Event::End
806    pub fn resolve_event<'i>(&self, event: Event<'i>) -> (ResolveResult<'_>, Event<'i>) {
807        use Event::*;
808
809        match event {
810            Empty(e) => (self.resolve_prefix(e.name().prefix(), true), Empty(e)),
811            Start(e) => (self.resolve_prefix(e.name().prefix(), true), Start(e)),
812            End(e) => (self.resolve_prefix(e.name().prefix(), true), End(e)),
813            e => (ResolveResult::Unbound, e),
814        }
815    }
816
817    /// Resolves given optional prefix (usually got from [`QName`]) into a corresponding namespace.
818    ///
819    /// # Parameters
820    /// - `prefix`: prefix to resolve, usually result of [`QName::prefix()`];
821    /// - `use_default`: whether to try to translate `None` prefix to the currently default namespace
822    ///   (bound using `xmlns="default namespace"`) or return [`ResolveResult::Unbound`].
823    ///   For attribute names this should be set to `false` and for element names to `true`.
824    pub fn resolve_prefix(&self, prefix: Option<Prefix>, use_default: bool) -> ResolveResult<'_> {
825        // Find the last defined binding that corresponds to the given prefix
826        let mut iter = self.bindings.iter().rev();
827        match (prefix, use_default) {
828            // Attribute name has no explicit prefix -> Unbound
829            (None, false) => ResolveResult::Unbound,
830            // Element name has no explicit prefix -> find nearest xmlns binding
831            (None, true) => match iter.find(|n| n.prefix_len == 0) {
832                Some(n) => n.namespace(&self.buffer),
833                None => ResolveResult::Unbound,
834            },
835            // Attribute or element name with explicit prefix
836            (Some(p), _) => match iter.find(|n| n.prefix(&self.buffer) == prefix) {
837                Some(n) if n.value_len != 0 => n.namespace(&self.buffer),
838                // Not found or binding reset (corresponds to `xmlns:p=""`)
839                _ => ResolveResult::Unknown(p.into_inner().to_vec()),
840            },
841        }
842    }
843
844    /// Returns all the bindings currently in effect except the default `xml` and `xmlns` bindings.
845    ///
846    /// # Examples
847    ///
848    /// This example shows what results the returned iterator would return after
849    /// reading each event of a simple XML.
850    ///
851    /// ```
852    /// # use pretty_assertions::assert_eq;
853    /// use quick_xml::name::{Namespace, PrefixDeclaration};
854    /// use quick_xml::NsReader;
855    ///
856    /// let src = "<root>
857    ///   <a xmlns=\"a1\" xmlns:a=\"a2\">
858    ///     <b xmlns=\"b1\" xmlns:b=\"b2\">
859    ///       <c/>
860    ///     </b>
861    ///     <d/>
862    ///   </a>
863    /// </root>";
864    /// let mut reader = NsReader::from_str(src);
865    /// reader.config_mut().trim_text(true);
866    /// // No bindings at the beginning
867    /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![]);
868    ///
869    /// reader.read_resolved_event()?; // <root>
870    /// // No bindings declared on root
871    /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![]);
872    ///
873    /// reader.read_resolved_event()?; // <a>
874    /// // Two bindings declared on "a"
875    /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![
876    ///     (PrefixDeclaration::Default, Namespace(b"a1")),
877    ///     (PrefixDeclaration::Named(b"a"), Namespace(b"a2"))
878    /// ]);
879    ///
880    /// reader.read_resolved_event()?; // <b>
881    /// // The default prefix got overridden and new "b" prefix
882    /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![
883    ///     (PrefixDeclaration::Named(b"a"), Namespace(b"a2")),
884    ///     (PrefixDeclaration::Default, Namespace(b"b1")),
885    ///     (PrefixDeclaration::Named(b"b"), Namespace(b"b2"))
886    /// ]);
887    ///
888    /// reader.read_resolved_event()?; // <c/>
889    /// // Still the same
890    /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![
891    ///     (PrefixDeclaration::Named(b"a"), Namespace(b"a2")),
892    ///     (PrefixDeclaration::Default, Namespace(b"b1")),
893    ///     (PrefixDeclaration::Named(b"b"), Namespace(b"b2"))
894    /// ]);
895    ///
896    /// reader.read_resolved_event()?; // </b>
897    /// // Still the same
898    /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![
899    ///     (PrefixDeclaration::Named(b"a"), Namespace(b"a2")),
900    ///     (PrefixDeclaration::Default, Namespace(b"b1")),
901    ///     (PrefixDeclaration::Named(b"b"), Namespace(b"b2"))
902    /// ]);
903    ///
904    /// reader.read_resolved_event()?; // <d/>
905    /// // </b> got closed so back to the bindings declared on <a>
906    /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![
907    ///     (PrefixDeclaration::Default, Namespace(b"a1")),
908    ///     (PrefixDeclaration::Named(b"a"), Namespace(b"a2"))
909    /// ]);
910    ///
911    /// reader.read_resolved_event()?; // </a>
912    /// // Still the same
913    /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![
914    ///     (PrefixDeclaration::Default, Namespace(b"a1")),
915    ///     (PrefixDeclaration::Named(b"a"), Namespace(b"a2"))
916    /// ]);
917    ///
918    /// reader.read_resolved_event()?; // </root>
919    /// // <a> got closed
920    /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![]);
921    /// # quick_xml::Result::Ok(())
922    /// ```
923    #[inline]
924    pub const fn bindings(&self) -> NamespaceBindingsIter<'_> {
925        NamespaceBindingsIter {
926            resolver: self,
927            // We initialize the cursor to 2 to skip the two default namespaces xml: and xmlns:
928            cursor: 2,
929        }
930    }
931
932    /// Returns all the bindings on the specified level, including the default
933    /// `xml` and `xmlns` bindings.
934    ///
935    /// # Parameters
936    /// - `level`: the nesting level of an XML tag. The document without tags has
937    ///   level 0, at which default bindings are declared. The root tag has level 1
938    ///   and all other tags has levels > 1. If specify level more than [current], the
939    ///   empty iterator is returned.
940    ///
941    /// # Examples
942    ///
943    /// This example shows what results the returned iterator would return on each
944    /// level after reaning some events of a simple XML.
945    ///
946    /// ```
947    /// # use pretty_assertions::assert_eq;
948    /// use quick_xml::name::{Namespace, PrefixDeclaration};
949    /// use quick_xml::NsReader;
950    ///
951    /// let src = "<root>
952    ///   <a xmlns=\"a1\" xmlns:a=\"a2\">
953    ///     <b xmlns=\"b1\" xmlns:b=\"b2\">
954    ///       <c/>
955    ///     </b>
956    ///     <d/>
957    ///   </a>
958    /// </root>";
959    /// let mut reader = NsReader::from_str(src);
960    /// reader.config_mut().trim_text(true);
961    /// reader.read_resolved_event()?; // <root>
962    /// reader.read_resolved_event()?; // <a>
963    /// reader.read_resolved_event()?; // <b>
964    /// reader.read_resolved_event()?; // <c/>
965    ///
966    /// // Default bindings at the beginning
967    /// assert_eq!(reader.resolver().bindings_of(0).collect::<Vec<_>>(), vec![
968    ///     (PrefixDeclaration::Named(b"xml"), Namespace(b"http://www.w3.org/XML/1998/namespace")),
969    ///     (PrefixDeclaration::Named(b"xmlns"), Namespace(b"http://www.w3.org/2000/xmlns/")),
970    /// ]);
971    ///
972    /// // No bindings declared on root
973    /// assert_eq!(reader.resolver().bindings_of(1).collect::<Vec<_>>(), vec![]);
974    ///
975    /// // Two bindings declared on "a"
976    /// assert_eq!(reader.resolver().bindings_of(2).collect::<Vec<_>>(), vec![
977    ///     (PrefixDeclaration::Default, Namespace(b"a1")),
978    ///     (PrefixDeclaration::Named(b"a"), Namespace(b"a2")),
979    /// ]);
980    ///
981    /// // Two bindings declared on "b"
982    /// assert_eq!(reader.resolver().bindings_of(3).collect::<Vec<_>>(), vec![
983    ///     (PrefixDeclaration::Default, Namespace(b"b1")),
984    ///     (PrefixDeclaration::Named(b"b"), Namespace(b"b2")),
985    /// ]);
986    ///
987    /// // No bindings declared on "c"
988    /// assert_eq!(reader.resolver().bindings_of(4).collect::<Vec<_>>(), vec![]);
989    ///
990    /// // No bindings on non-existent level
991    /// assert_eq!(reader.resolver().bindings_of(5).collect::<Vec<_>>(), vec![]);
992    /// # quick_xml::Result::Ok(())
993    /// ```
994    ///
995    /// [current]: Self::level
996    pub const fn bindings_of(&self, level: u16) -> NamespaceBindingsOfLevelIter<'_> {
997        NamespaceBindingsOfLevelIter {
998            resolver: self,
999            cursor: 0,
1000            level,
1001        }
1002    }
1003
1004    /// Returns the number of [`push`] calls that were not followed by [`pop`] calls.
1005    ///
1006    /// Due to use of `u16` for level number the number of nested tags in XML
1007    /// are limited by [`u16::MAX`], but that is enough for any real application.
1008    ///
1009    /// # Example
1010    ///
1011    /// ```
1012    /// # use pretty_assertions::assert_eq;
1013    /// # use quick_xml::events::BytesStart;
1014    /// # use quick_xml::name::{Namespace, NamespaceResolver, PrefixDeclaration, QName, ResolveResult};
1015    /// #
1016    /// let mut resolver = NamespaceResolver::default();
1017    ///
1018    /// assert_eq!(resolver.level(), 0);
1019    ///
1020    /// resolver.push(&BytesStart::new("tag"));
1021    /// assert_eq!(resolver.level(), 1);
1022    ///
1023    /// resolver.pop();
1024    /// assert_eq!(resolver.level(), 0);
1025    ///
1026    /// // pop from empty resolver does nothing
1027    /// resolver.pop();
1028    /// assert_eq!(resolver.level(), 0);
1029    /// ```
1030    ///
1031    /// [`push`]: Self::push
1032    /// [`pop`]: Self::pop
1033    pub const fn level(&self) -> u16 {
1034        self.nesting_level
1035    }
1036}
1037
1038////////////////////////////////////////////////////////////////////////////////////////////////////
1039
1040/// Iterator on the current declared namespace bindings. Returns pairs of the _(prefix, namespace)_.
1041///
1042/// See [`NamespaceResolver::bindings`] for documentation.
1043#[derive(Debug, Clone)]
1044pub struct NamespaceBindingsIter<'a> {
1045    resolver: &'a NamespaceResolver,
1046    cursor: usize,
1047}
1048
1049impl<'a> Iterator for NamespaceBindingsIter<'a> {
1050    type Item = (PrefixDeclaration<'a>, Namespace<'a>);
1051
1052    fn next(&mut self) -> Option<(PrefixDeclaration<'a>, Namespace<'a>)> {
1053        while let Some(binding) = self.resolver.bindings.get(self.cursor) {
1054            self.cursor += 1; // We increment for next read
1055
1056            // We check if the key has not been overridden by having a look
1057            // at the namespaces declared after in the array
1058            let prefix = binding.prefix(&self.resolver.buffer);
1059            if self.resolver.bindings[self.cursor..]
1060                .iter()
1061                .any(|ne| prefix == ne.prefix(&self.resolver.buffer))
1062            {
1063                continue; // Overridden
1064            }
1065            if let ResolveResult::Bound(namespace) = binding.namespace(&self.resolver.buffer) {
1066                let prefix = match prefix {
1067                    Some(Prefix(prefix)) => PrefixDeclaration::Named(prefix),
1068                    None => PrefixDeclaration::Default,
1069                };
1070                return Some((prefix, namespace));
1071            }
1072        }
1073        None // We have exhausted the array
1074    }
1075
1076    fn size_hint(&self) -> (usize, Option<usize>) {
1077        // Real count could be less if some namespaces was overridden
1078        (0, Some(self.resolver.bindings.len() - self.cursor))
1079    }
1080}
1081
1082impl<'a> FusedIterator for NamespaceBindingsIter<'a> {}
1083
1084/// The previous name for [`NamespaceBindingsIter`].
1085#[deprecated = "Use NamespaceBindingsIter instead. This alias will be removed in 0.40.0"]
1086pub type PrefixIter<'a> = NamespaceBindingsIter<'a>;
1087
1088/// Iterator on the declared namespace bindings on specified level. Returns pairs of the _(prefix, namespace)_.
1089///
1090/// See [`NamespaceResolver::bindings_of`] for documentation.
1091#[derive(Debug, Clone)]
1092pub struct NamespaceBindingsOfLevelIter<'a> {
1093    resolver: &'a NamespaceResolver,
1094    cursor: usize,
1095    level: u16,
1096}
1097
1098impl<'a> Iterator for NamespaceBindingsOfLevelIter<'a> {
1099    type Item = (PrefixDeclaration<'a>, Namespace<'a>);
1100
1101    fn next(&mut self) -> Option<(PrefixDeclaration<'a>, Namespace<'a>)> {
1102        while let Some(binding) = self.resolver.bindings.get(self.cursor) {
1103            self.cursor += 1; // We increment for next read
1104            if binding.level < self.level {
1105                continue;
1106            }
1107            if binding.level > self.level {
1108                break;
1109            }
1110
1111            if let ResolveResult::Bound(namespace) = binding.namespace(&self.resolver.buffer) {
1112                let prefix = match binding.prefix(&self.resolver.buffer) {
1113                    Some(Prefix(prefix)) => PrefixDeclaration::Named(prefix),
1114                    None => PrefixDeclaration::Default,
1115                };
1116                return Some((prefix, namespace));
1117            }
1118        }
1119        None // We have exhausted the array
1120    }
1121
1122    fn size_hint(&self) -> (usize, Option<usize>) {
1123        // Real count could be less
1124        (0, Some(self.resolver.bindings.len() - self.cursor))
1125    }
1126}
1127
1128impl<'a> FusedIterator for NamespaceBindingsOfLevelIter<'a> {}
1129
1130////////////////////////////////////////////////////////////////////////////////////////////////////
1131
1132#[cfg(test)]
1133mod namespaces {
1134    use super::*;
1135    use pretty_assertions::assert_eq;
1136    use ResolveResult::*;
1137
1138    /// Unprefixed attribute names (resolved with `false` flag) never have a namespace
1139    /// according to <https://www.w3.org/TR/xml-names11/#defaulting>:
1140    ///
1141    /// > A default namespace declaration applies to all unprefixed element names
1142    /// > within its scope. Default namespace declarations do not apply directly
1143    /// > to attribute names; the interpretation of unprefixed attributes is
1144    /// > determined by the element on which they appear.
1145    mod unprefixed {
1146        use super::*;
1147        use pretty_assertions::assert_eq;
1148
1149        /// Basic tests that checks that basic resolver functionality is working
1150        #[test]
1151        fn basic() {
1152            let name = QName(b"simple");
1153            let ns = Namespace(b"default");
1154
1155            let mut resolver = NamespaceResolver::default();
1156            let s = resolver.buffer.len();
1157
1158            resolver
1159                .push(&BytesStart::from_content(" xmlns='default'", 0))
1160                .unwrap();
1161            assert_eq!(&resolver.buffer[s..], b"default");
1162
1163            // Check that tags without namespaces does not change result
1164            resolver.push(&BytesStart::from_content("", 0)).unwrap();
1165            assert_eq!(&resolver.buffer[s..], b"default");
1166            resolver.pop();
1167
1168            assert_eq!(&resolver.buffer[s..], b"default");
1169            assert_eq!(
1170                resolver.resolve(name, true),
1171                (Bound(ns), LocalName(b"simple"))
1172            );
1173            assert_eq!(
1174                resolver.resolve(name, false),
1175                (Unbound, LocalName(b"simple"))
1176            );
1177        }
1178
1179        /// Test adding a second level of namespaces, which replaces the previous binding
1180        #[test]
1181        fn override_namespace() {
1182            let name = QName(b"simple");
1183            let old_ns = Namespace(b"old");
1184            let new_ns = Namespace(b"new");
1185
1186            let mut resolver = NamespaceResolver::default();
1187            let s = resolver.buffer.len();
1188
1189            resolver
1190                .push(&BytesStart::from_content(" xmlns='old'", 0))
1191                .unwrap();
1192            resolver
1193                .push(&BytesStart::from_content(" xmlns='new'", 0))
1194                .unwrap();
1195
1196            assert_eq!(&resolver.buffer[s..], b"oldnew");
1197            assert_eq!(
1198                resolver.resolve(name, true),
1199                (Bound(new_ns), LocalName(b"simple"))
1200            );
1201            assert_eq!(
1202                resolver.resolve(name, false),
1203                (Unbound, LocalName(b"simple"))
1204            );
1205
1206            resolver.pop();
1207            assert_eq!(&resolver.buffer[s..], b"old");
1208            assert_eq!(
1209                resolver.resolve(name, true),
1210                (Bound(old_ns), LocalName(b"simple"))
1211            );
1212            assert_eq!(
1213                resolver.resolve(name, false),
1214                (Unbound, LocalName(b"simple"))
1215            );
1216        }
1217
1218        /// Test adding a second level of namespaces, which reset the previous binding
1219        /// to not bound state by specifying an empty namespace name.
1220        ///
1221        /// See <https://www.w3.org/TR/xml-names11/#scoping>
1222        #[test]
1223        fn reset() {
1224            let name = QName(b"simple");
1225            let old_ns = Namespace(b"old");
1226
1227            let mut resolver = NamespaceResolver::default();
1228            let s = resolver.buffer.len();
1229
1230            resolver
1231                .push(&BytesStart::from_content(" xmlns='old'", 0))
1232                .unwrap();
1233            resolver
1234                .push(&BytesStart::from_content(" xmlns=''", 0))
1235                .unwrap();
1236
1237            assert_eq!(&resolver.buffer[s..], b"old");
1238            assert_eq!(
1239                resolver.resolve(name, true),
1240                (Unbound, LocalName(b"simple"))
1241            );
1242            assert_eq!(
1243                resolver.resolve(name, false),
1244                (Unbound, LocalName(b"simple"))
1245            );
1246
1247            resolver.pop();
1248            assert_eq!(&resolver.buffer[s..], b"old");
1249            assert_eq!(
1250                resolver.resolve(name, true),
1251                (Bound(old_ns), LocalName(b"simple"))
1252            );
1253            assert_eq!(
1254                resolver.resolve(name, false),
1255                (Unbound, LocalName(b"simple"))
1256            );
1257        }
1258    }
1259
1260    mod declared_prefix {
1261        use super::*;
1262        use pretty_assertions::assert_eq;
1263
1264        /// Basic tests that checks that basic resolver functionality is working
1265        #[test]
1266        fn basic() {
1267            let name = QName(b"p:with-declared-prefix");
1268            let ns = Namespace(b"default");
1269
1270            let mut resolver = NamespaceResolver::default();
1271            let s = resolver.buffer.len();
1272
1273            resolver
1274                .push(&BytesStart::from_content(" xmlns:p='default'", 0))
1275                .unwrap();
1276            assert_eq!(&resolver.buffer[s..], b"pdefault");
1277
1278            // Check that tags without namespaces does not change result
1279            resolver.push(&BytesStart::from_content("", 0)).unwrap();
1280            assert_eq!(&resolver.buffer[s..], b"pdefault");
1281            resolver.pop();
1282
1283            assert_eq!(&resolver.buffer[s..], b"pdefault");
1284            assert_eq!(
1285                resolver.resolve(name, true),
1286                (Bound(ns), LocalName(b"with-declared-prefix"))
1287            );
1288            assert_eq!(
1289                resolver.resolve(name, false),
1290                (Bound(ns), LocalName(b"with-declared-prefix"))
1291            );
1292        }
1293
1294        /// Test adding a second level of namespaces, which replaces the previous binding
1295        #[test]
1296        fn override_namespace() {
1297            let name = QName(b"p:with-declared-prefix");
1298            let old_ns = Namespace(b"old");
1299            let new_ns = Namespace(b"new");
1300
1301            let mut resolver = NamespaceResolver::default();
1302            let s = resolver.buffer.len();
1303
1304            resolver
1305                .push(&BytesStart::from_content(" xmlns:p='old'", 0))
1306                .unwrap();
1307            resolver
1308                .push(&BytesStart::from_content(" xmlns:p='new'", 0))
1309                .unwrap();
1310
1311            assert_eq!(&resolver.buffer[s..], b"poldpnew");
1312            assert_eq!(
1313                resolver.resolve(name, true),
1314                (Bound(new_ns), LocalName(b"with-declared-prefix"))
1315            );
1316            assert_eq!(
1317                resolver.resolve(name, false),
1318                (Bound(new_ns), LocalName(b"with-declared-prefix"))
1319            );
1320
1321            resolver.pop();
1322            assert_eq!(&resolver.buffer[s..], b"pold");
1323            assert_eq!(
1324                resolver.resolve(name, true),
1325                (Bound(old_ns), LocalName(b"with-declared-prefix"))
1326            );
1327            assert_eq!(
1328                resolver.resolve(name, false),
1329                (Bound(old_ns), LocalName(b"with-declared-prefix"))
1330            );
1331        }
1332
1333        /// Test adding a second level of namespaces, which reset the previous binding
1334        /// to not bound state by specifying an empty namespace name.
1335        ///
1336        /// See <https://www.w3.org/TR/xml-names11/#scoping>
1337        #[test]
1338        fn reset() {
1339            let name = QName(b"p:with-declared-prefix");
1340            let old_ns = Namespace(b"old");
1341
1342            let mut resolver = NamespaceResolver::default();
1343            let s = resolver.buffer.len();
1344
1345            resolver
1346                .push(&BytesStart::from_content(" xmlns:p='old'", 0))
1347                .unwrap();
1348            resolver
1349                .push(&BytesStart::from_content(" xmlns:p=''", 0))
1350                .unwrap();
1351
1352            assert_eq!(&resolver.buffer[s..], b"poldp");
1353            assert_eq!(
1354                resolver.resolve(name, true),
1355                (Unknown(b"p".to_vec()), LocalName(b"with-declared-prefix"))
1356            );
1357            assert_eq!(
1358                resolver.resolve(name, false),
1359                (Unknown(b"p".to_vec()), LocalName(b"with-declared-prefix"))
1360            );
1361
1362            resolver.pop();
1363            assert_eq!(&resolver.buffer[s..], b"pold");
1364            assert_eq!(
1365                resolver.resolve(name, true),
1366                (Bound(old_ns), LocalName(b"with-declared-prefix"))
1367            );
1368            assert_eq!(
1369                resolver.resolve(name, false),
1370                (Bound(old_ns), LocalName(b"with-declared-prefix"))
1371            );
1372        }
1373    }
1374
1375    /// Tests for `xml` and `xmlns` built-in prefixes.
1376    ///
1377    /// See <https://www.w3.org/TR/xml-names11/#xmlReserved>
1378    mod builtin_prefixes {
1379        use super::*;
1380
1381        mod xml {
1382            use super::*;
1383            use pretty_assertions::assert_eq;
1384
1385            /// `xml` prefix are always defined, it is not required to define it explicitly.
1386            #[test]
1387            fn undeclared() {
1388                let name = QName(b"xml:random");
1389                let namespace = RESERVED_NAMESPACE_XML.1;
1390
1391                let resolver = NamespaceResolver::default();
1392
1393                assert_eq!(
1394                    resolver.resolve(name, true),
1395                    (Bound(namespace), LocalName(b"random"))
1396                );
1397
1398                assert_eq!(
1399                    resolver.resolve(name, false),
1400                    (Bound(namespace), LocalName(b"random"))
1401                );
1402            }
1403
1404            /// `xml` prefix can be declared but it must be bound to the value
1405            /// `http://www.w3.org/XML/1998/namespace`
1406            #[test]
1407            fn rebound_to_correct_ns() {
1408                let mut resolver = NamespaceResolver::default();
1409                let s = resolver.buffer.len();
1410                resolver.push(
1411                    &BytesStart::from_content(
1412                        " xmlns:xml='http://www.w3.org/XML/1998/namespace'",
1413                        0,
1414                    ),
1415                ).expect("`xml` prefix should be possible to bound to `http://www.w3.org/XML/1998/namespace`");
1416                assert_eq!(&resolver.buffer[s..], b"");
1417            }
1418
1419            /// `xml` prefix cannot be re-declared to another namespace
1420            #[test]
1421            fn rebound_to_incorrect_ns() {
1422                let mut resolver = NamespaceResolver::default();
1423                let s = resolver.buffer.len();
1424                assert_eq!(
1425                    resolver.push(&BytesStart::from_content(
1426                        " xmlns:xml='not_correct_namespace'",
1427                        0,
1428                    )),
1429                    Err(NamespaceError::InvalidXmlPrefixBind(
1430                        b"not_correct_namespace".to_vec()
1431                    )),
1432                );
1433                assert_eq!(&resolver.buffer[s..], b"");
1434            }
1435
1436            /// `xml` prefix cannot be unbound
1437            #[test]
1438            fn unbound() {
1439                let mut resolver = NamespaceResolver::default();
1440                let s = resolver.buffer.len();
1441                assert_eq!(
1442                    resolver.push(&BytesStart::from_content(" xmlns:xml=''", 0)),
1443                    Err(NamespaceError::InvalidXmlPrefixBind(b"".to_vec())),
1444                );
1445                assert_eq!(&resolver.buffer[s..], b"");
1446            }
1447
1448            /// Other prefix cannot be bound to `xml` namespace
1449            #[test]
1450            fn other_prefix_bound_to_xml_namespace() {
1451                let mut resolver = NamespaceResolver::default();
1452                let s = resolver.buffer.len();
1453                assert_eq!(
1454                    resolver.push(&BytesStart::from_content(
1455                        " xmlns:not_xml='http://www.w3.org/XML/1998/namespace'",
1456                        0,
1457                    )),
1458                    Err(NamespaceError::InvalidPrefixForXml(b"not_xml".to_vec())),
1459                );
1460                assert_eq!(&resolver.buffer[s..], b"");
1461            }
1462        }
1463
1464        mod xmlns {
1465            use super::*;
1466            use pretty_assertions::assert_eq;
1467
1468            /// `xmlns` prefix are always defined, it is forbidden to define it explicitly
1469            #[test]
1470            fn undeclared() {
1471                let name = QName(b"xmlns:random");
1472                let namespace = RESERVED_NAMESPACE_XMLNS.1;
1473
1474                let resolver = NamespaceResolver::default();
1475
1476                assert_eq!(
1477                    resolver.resolve(name, true),
1478                    (Bound(namespace), LocalName(b"random"))
1479                );
1480
1481                assert_eq!(
1482                    resolver.resolve(name, false),
1483                    (Bound(namespace), LocalName(b"random"))
1484                );
1485            }
1486
1487            /// `xmlns` prefix cannot be re-declared event to its own namespace
1488            #[test]
1489            fn rebound_to_correct_ns() {
1490                let mut resolver = NamespaceResolver::default();
1491                let s = resolver.buffer.len();
1492                assert_eq!(
1493                    resolver.push(&BytesStart::from_content(
1494                        " xmlns:xmlns='http://www.w3.org/2000/xmlns/'",
1495                        0,
1496                    )),
1497                    Err(NamespaceError::InvalidXmlnsPrefixBind(
1498                        b"http://www.w3.org/2000/xmlns/".to_vec()
1499                    )),
1500                );
1501                assert_eq!(&resolver.buffer[s..], b"");
1502            }
1503
1504            /// `xmlns` prefix cannot be re-declared
1505            #[test]
1506            fn rebound_to_incorrect_ns() {
1507                let mut resolver = NamespaceResolver::default();
1508                let s = resolver.buffer.len();
1509                assert_eq!(
1510                    resolver.push(&BytesStart::from_content(
1511                        " xmlns:xmlns='not_correct_namespace'",
1512                        0,
1513                    )),
1514                    Err(NamespaceError::InvalidXmlnsPrefixBind(
1515                        b"not_correct_namespace".to_vec()
1516                    )),
1517                );
1518                assert_eq!(&resolver.buffer[s..], b"");
1519            }
1520
1521            /// `xmlns` prefix cannot be unbound
1522            #[test]
1523            fn unbound() {
1524                let mut resolver = NamespaceResolver::default();
1525                let s = resolver.buffer.len();
1526                assert_eq!(
1527                    resolver.push(&BytesStart::from_content(" xmlns:xmlns=''", 0)),
1528                    Err(NamespaceError::InvalidXmlnsPrefixBind(b"".to_vec())),
1529                );
1530                assert_eq!(&resolver.buffer[s..], b"");
1531            }
1532
1533            /// Other prefix cannot be bound to `xmlns` namespace
1534            #[test]
1535            fn other_prefix_bound_to_xmlns_namespace() {
1536                let mut resolver = NamespaceResolver::default();
1537                let s = resolver.buffer.len();
1538                assert_eq!(
1539                    resolver.push(&BytesStart::from_content(
1540                        " xmlns:not_xmlns='http://www.w3.org/2000/xmlns/'",
1541                        0,
1542                    )),
1543                    Err(NamespaceError::InvalidPrefixForXmlns(b"not_xmlns".to_vec())),
1544                );
1545                assert_eq!(&resolver.buffer[s..], b"");
1546            }
1547        }
1548    }
1549
1550    #[test]
1551    fn undeclared_prefix() {
1552        let name = QName(b"unknown:prefix");
1553
1554        let resolver = NamespaceResolver::default();
1555
1556        assert_eq!(
1557            resolver.buffer,
1558            b"xmlhttp://www.w3.org/XML/1998/namespacexmlnshttp://www.w3.org/2000/xmlns/"
1559        );
1560        assert_eq!(
1561            resolver.resolve(name, true),
1562            (Unknown(b"unknown".to_vec()), LocalName(b"prefix"))
1563        );
1564        assert_eq!(
1565            resolver.resolve(name, false),
1566            (Unknown(b"unknown".to_vec()), LocalName(b"prefix"))
1567        );
1568    }
1569
1570    /// Checks how the QName is decomposed to a prefix and a local name
1571    #[test]
1572    fn prefix_and_local_name() {
1573        let name = QName(b"foo:bus");
1574        assert_eq!(name.prefix(), Some(Prefix(b"foo")));
1575        assert_eq!(name.local_name(), LocalName(b"bus"));
1576        assert_eq!(name.decompose(), (LocalName(b"bus"), Some(Prefix(b"foo"))));
1577
1578        let name = QName(b"foo:");
1579        assert_eq!(name.prefix(), Some(Prefix(b"foo")));
1580        assert_eq!(name.local_name(), LocalName(b""));
1581        assert_eq!(name.decompose(), (LocalName(b""), Some(Prefix(b"foo"))));
1582
1583        let name = QName(b":foo");
1584        assert_eq!(name.prefix(), Some(Prefix(b"")));
1585        assert_eq!(name.local_name(), LocalName(b"foo"));
1586        assert_eq!(name.decompose(), (LocalName(b"foo"), Some(Prefix(b""))));
1587
1588        let name = QName(b"foo:bus:baz");
1589        assert_eq!(name.prefix(), Some(Prefix(b"foo")));
1590        assert_eq!(name.local_name(), LocalName(b"bus:baz"));
1591        assert_eq!(
1592            name.decompose(),
1593            (LocalName(b"bus:baz"), Some(Prefix(b"foo")))
1594        );
1595    }
1596}