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;
8use crate::utils::write_byte_string;
9use memchr::memchr;
10use std::fmt::{self, Debug, Formatter};
11
12/// Some namespace was invalid
13#[derive(Debug, Clone, PartialEq, Eq)]
14pub enum NamespaceError {
15    /// Specified namespace prefix is unknown, cannot resolve namespace for it
16    UnknownPrefix(Vec<u8>),
17    /// Attempts to bind the `xml` prefix to something other than `http://www.w3.org/XML/1998/namespace`.
18    ///
19    /// `xml` prefix can be bound only to `http://www.w3.org/XML/1998/namespace`.
20    ///
21    /// Contains the namespace to which `xml` tried to be bound.
22    InvalidXmlPrefixBind(Vec<u8>),
23    /// Attempts to bind the `xmlns` prefix.
24    ///
25    /// `xmlns` prefix is always bound to `http://www.w3.org/2000/xmlns/` and cannot be bound
26    /// to any other namespace or even to `http://www.w3.org/2000/xmlns/`.
27    ///
28    /// Contains the namespace to which `xmlns` tried to be bound.
29    InvalidXmlnsPrefixBind(Vec<u8>),
30    /// Attempts to bind some prefix (except `xml`) to `http://www.w3.org/XML/1998/namespace`.
31    ///
32    /// Only `xml` prefix can be bound to `http://www.w3.org/XML/1998/namespace`.
33    ///
34    /// Contains the prefix that is tried to be bound.
35    InvalidPrefixForXml(Vec<u8>),
36    /// Attempts to bind some prefix to `http://www.w3.org/2000/xmlns/`.
37    ///
38    /// `http://www.w3.org/2000/xmlns/` cannot be bound to any prefix, even to `xmlns`.
39    ///
40    /// Contains the prefix that is tried to be bound.
41    InvalidPrefixForXmlns(Vec<u8>),
42}
43
44impl fmt::Display for NamespaceError {
45    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
46        match self {
47            Self::UnknownPrefix(prefix) => {
48                f.write_str("unknown namespace prefix '")?;
49                write_byte_string(f, prefix)?;
50                f.write_str("'")
51            }
52            Self::InvalidXmlPrefixBind(namespace) => {
53                f.write_str("the namespace prefix 'xml' cannot be bound to '")?;
54                write_byte_string(f, namespace)?;
55                f.write_str("'")
56            }
57            Self::InvalidXmlnsPrefixBind(namespace) => {
58                f.write_str("the namespace prefix 'xmlns' cannot be bound to '")?;
59                write_byte_string(f, namespace)?;
60                f.write_str("'")
61            }
62            Self::InvalidPrefixForXml(prefix) => {
63                f.write_str("the namespace prefix '")?;
64                write_byte_string(f, prefix)?;
65                f.write_str("' cannot be bound to 'http://www.w3.org/XML/1998/namespace'")
66            }
67            Self::InvalidPrefixForXmlns(prefix) => {
68                f.write_str("the namespace prefix '")?;
69                write_byte_string(f, prefix)?;
70                f.write_str("' cannot be bound to 'http://www.w3.org/2000/xmlns/'")
71            }
72        }
73    }
74}
75
76impl std::error::Error for NamespaceError {}
77
78////////////////////////////////////////////////////////////////////////////////////////////////////
79
80/// A [qualified name] of an element or an attribute, including an optional
81/// namespace [prefix](Prefix) and a [local name](LocalName).
82///
83/// [qualified name]: https://www.w3.org/TR/xml-names11/#dt-qualname
84#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
85#[cfg_attr(feature = "serde-types", derive(serde::Deserialize, serde::Serialize))]
86pub struct QName<'a>(pub &'a [u8]);
87impl<'a> QName<'a> {
88    /// Converts this name to an internal slice representation.
89    #[inline(always)]
90    pub const fn into_inner(self) -> &'a [u8] {
91        self.0
92    }
93
94    /// Returns local part of this qualified name.
95    ///
96    /// All content up to and including the first `:` character is removed from
97    /// the tag name.
98    ///
99    /// # Examples
100    ///
101    /// ```
102    /// # use quick_xml::name::QName;
103    /// let simple = QName(b"simple-name");
104    /// assert_eq!(simple.local_name().as_ref(), b"simple-name");
105    ///
106    /// let qname = QName(b"namespace:simple-name");
107    /// assert_eq!(qname.local_name().as_ref(), b"simple-name");
108    /// ```
109    pub fn local_name(&self) -> LocalName<'a> {
110        LocalName(self.index().map_or(self.0, |i| &self.0[i + 1..]))
111    }
112
113    /// Returns namespace part of this qualified name or `None` if namespace part
114    /// is not defined (symbol `':'` not found).
115    ///
116    /// # Examples
117    ///
118    /// ```
119    /// # use std::convert::AsRef;
120    /// # use quick_xml::name::QName;
121    /// let simple = QName(b"simple-name");
122    /// assert_eq!(simple.prefix(), None);
123    ///
124    /// let qname = QName(b"prefix:simple-name");
125    /// assert_eq!(qname.prefix().as_ref().map(|n| n.as_ref()), Some(b"prefix".as_ref()));
126    /// ```
127    pub fn prefix(&self) -> Option<Prefix<'a>> {
128        self.index().map(|i| Prefix(&self.0[..i]))
129    }
130
131    /// The same as `(qname.local_name(), qname.prefix())`, but does only one
132    /// lookup for a `':'` symbol.
133    pub fn decompose(&self) -> (LocalName<'a>, Option<Prefix<'a>>) {
134        match self.index() {
135            None => (LocalName(self.0), None),
136            Some(i) => (LocalName(&self.0[i + 1..]), Some(Prefix(&self.0[..i]))),
137        }
138    }
139
140    /// If that `QName` represents `"xmlns"` series of names, returns `Some`,
141    /// otherwise `None` is returned.
142    ///
143    /// # Examples
144    ///
145    /// ```
146    /// # use quick_xml::name::{QName, PrefixDeclaration};
147    /// let qname = QName(b"xmlns");
148    /// assert_eq!(qname.as_namespace_binding(), Some(PrefixDeclaration::Default));
149    ///
150    /// let qname = QName(b"xmlns:prefix");
151    /// assert_eq!(qname.as_namespace_binding(), Some(PrefixDeclaration::Named(b"prefix")));
152    ///
153    /// // Be aware that this method does not check the validity of the prefix - it can be empty!
154    /// let qname = QName(b"xmlns:");
155    /// assert_eq!(qname.as_namespace_binding(), Some(PrefixDeclaration::Named(b"")));
156    ///
157    /// let qname = QName(b"other-name");
158    /// assert_eq!(qname.as_namespace_binding(), None);
159    ///
160    /// // https://www.w3.org/TR/xml-names11/#xmlReserved
161    /// let qname = QName(b"xmlns-reserved-name");
162    /// assert_eq!(qname.as_namespace_binding(), None);
163    /// ```
164    pub fn as_namespace_binding(&self) -> Option<PrefixDeclaration<'a>> {
165        if self.0.starts_with(b"xmlns") {
166            return match self.0.get(5) {
167                None => Some(PrefixDeclaration::Default),
168                Some(&b':') => Some(PrefixDeclaration::Named(&self.0[6..])),
169                _ => None,
170            };
171        }
172        None
173    }
174
175    /// Returns the index in the name where prefix ended
176    #[inline(always)]
177    fn index(&self) -> Option<usize> {
178        memchr(b':', self.0)
179    }
180}
181impl<'a> Debug for QName<'a> {
182    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
183        write!(f, "QName(")?;
184        write_byte_string(f, self.0)?;
185        write!(f, ")")
186    }
187}
188impl<'a> AsRef<[u8]> for QName<'a> {
189    #[inline]
190    fn as_ref(&self) -> &[u8] {
191        self.0
192    }
193}
194
195////////////////////////////////////////////////////////////////////////////////////////////////////
196
197/// A [local (unqualified) name] of an element or an attribute, i.e. a name
198/// without [prefix](Prefix).
199///
200/// [local (unqualified) name]: https://www.w3.org/TR/xml-names11/#dt-localname
201#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
202#[cfg_attr(feature = "serde-types", derive(serde::Deserialize, serde::Serialize))]
203pub struct LocalName<'a>(pub(crate) &'a [u8]);
204impl<'a> LocalName<'a> {
205    /// Converts this name to an internal slice representation.
206    #[inline(always)]
207    pub const fn into_inner(self) -> &'a [u8] {
208        self.0
209    }
210}
211impl<'a> Debug for LocalName<'a> {
212    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
213        write!(f, "LocalName(")?;
214        write_byte_string(f, self.0)?;
215        write!(f, ")")
216    }
217}
218impl<'a> AsRef<[u8]> for LocalName<'a> {
219    #[inline]
220    fn as_ref(&self) -> &[u8] {
221        self.0
222    }
223}
224impl<'a> From<QName<'a>> for LocalName<'a> {
225    /// Creates `LocalName` from a [`QName`]
226    ///
227    /// # Examples
228    ///
229    /// ```
230    /// # use quick_xml::name::{LocalName, QName};
231    ///
232    /// let local: LocalName = QName(b"unprefixed").into();
233    /// assert_eq!(local.as_ref(), b"unprefixed");
234    ///
235    /// let local: LocalName = QName(b"some:prefix").into();
236    /// assert_eq!(local.as_ref(), b"prefix");
237    /// ```
238    #[inline]
239    fn from(name: QName<'a>) -> Self {
240        Self(name.index().map_or(name.0, |i| &name.0[i + 1..]))
241    }
242}
243
244////////////////////////////////////////////////////////////////////////////////////////////////////
245
246/// A [namespace prefix] part of the [qualified name](QName) of an element tag
247/// or an attribute: a `prefix` in `<prefix:local-element-name>` or
248/// `prefix:local-attribute-name="attribute value"`.
249///
250/// [namespace prefix]: https://www.w3.org/TR/xml-names11/#dt-prefix
251#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
252#[cfg_attr(feature = "serde-types", derive(serde::Deserialize, serde::Serialize))]
253pub struct Prefix<'a>(&'a [u8]);
254impl<'a> Prefix<'a> {
255    /// Extracts internal slice
256    #[inline(always)]
257    pub const fn into_inner(self) -> &'a [u8] {
258        self.0
259    }
260}
261impl<'a> Debug for Prefix<'a> {
262    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
263        write!(f, "Prefix(")?;
264        write_byte_string(f, self.0)?;
265        write!(f, ")")
266    }
267}
268impl<'a> AsRef<[u8]> for Prefix<'a> {
269    #[inline]
270    fn as_ref(&self) -> &[u8] {
271        self.0
272    }
273}
274
275////////////////////////////////////////////////////////////////////////////////////////////////////
276
277/// A namespace prefix declaration, `xmlns` or `xmlns:<name>`, as defined in
278/// [XML Schema specification](https://www.w3.org/TR/xml-names11/#ns-decl)
279#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
280pub enum PrefixDeclaration<'a> {
281    /// XML attribute binds a default namespace. Corresponds to `xmlns` in `xmlns="..."`
282    Default,
283    /// XML attribute binds a specified prefix to a namespace. Corresponds to a
284    /// `prefix` in `xmlns:prefix="..."`, which is stored as payload of this variant.
285    Named(&'a [u8]),
286}
287
288////////////////////////////////////////////////////////////////////////////////////////////////////
289
290/// A [namespace name] that is declared in a `xmlns[:prefix]="namespace name"`.
291///
292/// [namespace name]: https://www.w3.org/TR/xml-names11/#dt-NSName
293#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
294#[cfg_attr(feature = "serde-types", derive(serde::Deserialize, serde::Serialize))]
295pub struct Namespace<'a>(pub &'a [u8]);
296impl<'a> Namespace<'a> {
297    /// Converts this namespace to an internal slice representation.
298    ///
299    /// This is [non-normalized] attribute value, i.e. any entity references is
300    /// not expanded and space characters are not removed. This means, that
301    /// different byte slices, returned from this method, can represent the same
302    /// namespace and would be treated by parser as identical.
303    ///
304    /// For example, if the entity **eacute** has been defined to be **é**,
305    /// the empty tags below all contain namespace declarations binding the
306    /// prefix `p` to the same [IRI reference], `http://example.org/rosé`.
307    ///
308    /// ```xml
309    /// <p:foo xmlns:p="http://example.org/rosé" />
310    /// <p:foo xmlns:p="http://example.org/ros&#xe9;" />
311    /// <p:foo xmlns:p="http://example.org/ros&#xE9;" />
312    /// <p:foo xmlns:p="http://example.org/ros&#233;" />
313    /// <p:foo xmlns:p="http://example.org/ros&eacute;" />
314    /// ```
315    ///
316    /// This is because XML entity references are expanded during attribute value
317    /// normalization.
318    ///
319    /// [non-normalized]: https://www.w3.org/TR/xml11/#AVNormalize
320    /// [IRI reference]: https://datatracker.ietf.org/doc/html/rfc3987
321    #[inline(always)]
322    pub const fn into_inner(self) -> &'a [u8] {
323        self.0
324    }
325    //TODO: implement value normalization and use it when comparing namespaces
326}
327impl<'a> Debug for Namespace<'a> {
328    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
329        write!(f, "Namespace(")?;
330        write_byte_string(f, self.0)?;
331        write!(f, ")")
332    }
333}
334impl<'a> AsRef<[u8]> for Namespace<'a> {
335    #[inline]
336    fn as_ref(&self) -> &[u8] {
337        self.0
338    }
339}
340
341////////////////////////////////////////////////////////////////////////////////////////////////////
342
343/// Result of [prefix] resolution which creates by [`NsReader::resolve_attribute`],
344/// [`NsReader::resolve_element`], [`NsReader::read_resolved_event`] and
345/// [`NsReader::read_resolved_event_into`] methods.
346///
347/// [prefix]: Prefix
348/// [`NsReader::resolve_attribute`]: crate::reader::NsReader::resolve_attribute
349/// [`NsReader::resolve_element`]: crate::reader::NsReader::resolve_element
350/// [`NsReader::read_resolved_event`]: crate::reader::NsReader::read_resolved_event
351/// [`NsReader::read_resolved_event_into`]: crate::reader::NsReader::read_resolved_event_into
352#[derive(Clone, PartialEq, Eq, Hash)]
353pub enum ResolveResult<'ns> {
354    /// Qualified name does not contain prefix, and resolver does not define
355    /// default namespace, so name is not bound to any namespace
356    Unbound,
357    /// [`Prefix`] resolved to the specified namespace
358    Bound(Namespace<'ns>),
359    /// Specified prefix was not found in scope
360    Unknown(Vec<u8>),
361}
362impl<'ns> Debug for ResolveResult<'ns> {
363    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
364        match self {
365            Self::Unbound => write!(f, "Unbound"),
366            Self::Bound(ns) => write!(f, "Bound({:?})", ns),
367            Self::Unknown(p) => {
368                write!(f, "Unknown(")?;
369                write_byte_string(f, p)?;
370                write!(f, ")")
371            }
372        }
373    }
374}
375
376impl<'ns> TryFrom<ResolveResult<'ns>> for Option<Namespace<'ns>> {
377    type Error = NamespaceError;
378
379    /// Try to convert this result to an optional namespace and returns
380    /// [`NamespaceError::UnknownPrefix`] if this result represents unknown prefix
381    fn try_from(result: ResolveResult<'ns>) -> Result<Self, NamespaceError> {
382        use ResolveResult::*;
383
384        match result {
385            Unbound => Ok(None),
386            Bound(ns) => Ok(Some(ns)),
387            Unknown(p) => Err(NamespaceError::UnknownPrefix(p)),
388        }
389    }
390}
391
392////////////////////////////////////////////////////////////////////////////////////////////////////
393
394/// An entry that contains index into the buffer with namespace bindings.
395///
396/// Defines a mapping from *[namespace prefix]* to *[namespace name]*.
397/// If prefix is empty, defines a *default namespace* binding that applies to
398/// unprefixed element names (unprefixed attribute names do not bind to any
399/// namespace and they processing is dependent on the element in which their
400/// defined).
401///
402/// [namespace prefix]: https://www.w3.org/TR/xml-names11/#dt-prefix
403/// [namespace name]: https://www.w3.org/TR/xml-names11/#dt-NSName
404#[derive(Debug, Clone)]
405struct NamespaceEntry {
406    /// Index of the namespace in the buffer
407    start: usize,
408    /// Length of the prefix
409    /// * if greater than zero, then binds this namespace to the slice
410    ///   `[start..start + prefix_len]` in the buffer.
411    /// * else defines the current default namespace.
412    prefix_len: usize,
413    /// The length of a namespace name (the URI) of this namespace declaration.
414    /// Name started just after prefix and extend for `value_len` bytes.
415    ///
416    /// The XML standard [specifies] that an empty namespace value 'removes' a namespace declaration
417    /// for the extent of its scope. For prefix declarations that's not very interesting, but it is
418    /// vital for default namespace declarations. With `xmlns=""` you can revert back to the default
419    /// behaviour of leaving unqualified element names unqualified.
420    ///
421    /// [specifies]: https://www.w3.org/TR/xml-names11/#scoping
422    value_len: usize,
423    /// Level of nesting at which this namespace was declared. The declaring element is included,
424    /// i.e., a declaration on the document root has `level = 1`.
425    /// This is used to pop the namespace when the element gets closed.
426    level: i32,
427}
428
429impl NamespaceEntry {
430    /// Get the namespace prefix, bound to this namespace declaration, or `None`,
431    /// if this declaration is for default namespace (`xmlns="..."`).
432    #[inline]
433    fn prefix<'b>(&self, ns_buffer: &'b [u8]) -> Option<Prefix<'b>> {
434        if self.prefix_len == 0 {
435            None
436        } else {
437            Some(Prefix(&ns_buffer[self.start..self.start + self.prefix_len]))
438        }
439    }
440
441    /// Gets the namespace name (the URI) slice out of namespace buffer
442    ///
443    /// Returns `None` if namespace for this prefix was explicitly removed from
444    /// scope, using `xmlns[:prefix]=""`
445    #[inline]
446    fn namespace<'ns>(&self, buffer: &'ns [u8]) -> ResolveResult<'ns> {
447        if self.value_len == 0 {
448            ResolveResult::Unbound
449        } else {
450            let start = self.start + self.prefix_len;
451            ResolveResult::Bound(Namespace(&buffer[start..start + self.value_len]))
452        }
453    }
454}
455
456/// A namespace management buffer.
457///
458/// Holds all internal logic to push/pop namespaces with their levels.
459#[derive(Debug, Clone)]
460pub(crate) struct NamespaceResolver {
461    /// Buffer that contains names of namespace prefixes (the part between `xmlns:`
462    /// and an `=`) and namespace values.
463    buffer: Vec<u8>,
464    /// A stack of namespace bindings to prefixes that currently in scope
465    bindings: Vec<NamespaceEntry>,
466    /// The number of open tags at the moment. We need to keep track of this to know which namespace
467    /// declarations to remove when we encounter an `End` event.
468    nesting_level: i32,
469}
470
471/// That constant define the one of [reserved namespaces] for the xml standard.
472///
473/// The prefix `xml` is by definition bound to the namespace name
474/// `http://www.w3.org/XML/1998/namespace`. It may, but need not, be declared, and must not be
475/// undeclared or bound to any other namespace name. Other prefixes must not be bound to this
476/// namespace name, and it must not be declared as the default namespace.
477///
478/// [reserved namespaces]: https://www.w3.org/TR/xml-names11/#xmlReserved
479const RESERVED_NAMESPACE_XML: (Prefix, Namespace) = (
480    Prefix(b"xml"),
481    Namespace(b"http://www.w3.org/XML/1998/namespace"),
482);
483/// That constant define the one of [reserved namespaces] for the xml standard.
484///
485/// The prefix `xmlns` is used only to declare namespace bindings and is by definition bound
486/// to the namespace name `http://www.w3.org/2000/xmlns/`. It must not be declared or
487/// undeclared. Other prefixes must not be bound to this namespace name, and it must not be
488///  declared as the default namespace. Element names must not have the prefix `xmlns`.
489///
490/// [reserved namespaces]: https://www.w3.org/TR/xml-names11/#xmlReserved
491const RESERVED_NAMESPACE_XMLNS: (Prefix, Namespace) = (
492    Prefix(b"xmlns"),
493    Namespace(b"http://www.w3.org/2000/xmlns/"),
494);
495
496impl Default for NamespaceResolver {
497    fn default() -> Self {
498        let mut buffer = Vec::new();
499        let mut bindings = Vec::new();
500        for ent in &[RESERVED_NAMESPACE_XML, RESERVED_NAMESPACE_XMLNS] {
501            let prefix = ent.0.into_inner();
502            let uri = ent.1.into_inner();
503            bindings.push(NamespaceEntry {
504                start: buffer.len(),
505                prefix_len: prefix.len(),
506                value_len: uri.len(),
507                level: 0,
508            });
509            buffer.extend(prefix);
510            buffer.extend(uri);
511        }
512
513        Self {
514            buffer,
515            bindings,
516            nesting_level: 0,
517        }
518    }
519}
520
521impl NamespaceResolver {
522    /// Begins a new scope and add to it all [namespace bindings] that found in
523    /// the specified start element.
524    ///
525    /// [namespace binding]: https://www.w3.org/TR/xml-names11/#dt-NSDecl
526    pub fn push(&mut self, start: &BytesStart) -> Result<(), NamespaceError> {
527        self.nesting_level += 1;
528        let level = self.nesting_level;
529        // adds new namespaces for attributes starting with 'xmlns:' and for the 'xmlns'
530        // (default namespace) attribute.
531        for a in start.attributes().with_checks(false) {
532            if let Ok(Attribute { key: k, value: v }) = a {
533                match k.as_namespace_binding() {
534                    Some(PrefixDeclaration::Default) => {
535                        let start = self.buffer.len();
536                        self.buffer.extend_from_slice(&v);
537                        self.bindings.push(NamespaceEntry {
538                            start,
539                            prefix_len: 0,
540                            value_len: v.len(),
541                            level,
542                        });
543                    }
544                    Some(PrefixDeclaration::Named(b"xml")) => {
545                        if Namespace(&v) != RESERVED_NAMESPACE_XML.1 {
546                            // error, `xml` prefix explicitly set to different value
547                            return Err(NamespaceError::InvalidXmlPrefixBind(v.to_vec()));
548                        }
549                        // don't add another NamespaceEntry for the `xml` namespace prefix
550                    }
551                    Some(PrefixDeclaration::Named(b"xmlns")) => {
552                        // error, `xmlns` prefix explicitly set
553                        return Err(NamespaceError::InvalidXmlnsPrefixBind(v.to_vec()));
554                    }
555                    Some(PrefixDeclaration::Named(prefix)) => {
556                        let ns = Namespace(&v);
557
558                        if ns == RESERVED_NAMESPACE_XML.1 {
559                            // error, non-`xml` prefix set to xml uri
560                            return Err(NamespaceError::InvalidPrefixForXml(prefix.to_vec()));
561                        } else if ns == RESERVED_NAMESPACE_XMLNS.1 {
562                            // error, non-`xmlns` prefix set to xmlns uri
563                            return Err(NamespaceError::InvalidPrefixForXmlns(prefix.to_vec()));
564                        }
565
566                        let start = self.buffer.len();
567                        self.buffer.extend_from_slice(prefix);
568                        self.buffer.extend_from_slice(&v);
569                        self.bindings.push(NamespaceEntry {
570                            start,
571                            prefix_len: prefix.len(),
572                            value_len: v.len(),
573                            level,
574                        });
575                    }
576                    None => {}
577                }
578            } else {
579                break;
580            }
581        }
582        Ok(())
583    }
584
585    /// Ends a top-most scope by popping all [namespace binding], that was added by
586    /// last call to [`Self::push()`].
587    ///
588    /// [namespace binding]: https://www.w3.org/TR/xml-names11/#dt-NSDecl
589    pub fn pop(&mut self) {
590        self.nesting_level -= 1;
591        let current_level = self.nesting_level;
592        // from the back (most deeply nested scope), look for the first scope that is still valid
593        match self.bindings.iter().rposition(|n| n.level <= current_level) {
594            // none of the namespaces are valid, remove all of them
595            None => {
596                self.buffer.clear();
597                self.bindings.clear();
598            }
599            // drop all namespaces past the last valid namespace
600            Some(last_valid_pos) => {
601                if let Some(len) = self.bindings.get(last_valid_pos + 1).map(|n| n.start) {
602                    self.buffer.truncate(len);
603                    self.bindings.truncate(last_valid_pos + 1);
604                }
605            }
606        }
607    }
608
609    /// Resolves a potentially qualified **element name** or **attribute name**
610    /// into (namespace name, local name).
611    ///
612    /// *Qualified* names have the form `prefix:local-name` where the `prefix` is
613    /// defined on any containing XML element via `xmlns:prefix="the:namespace:uri"`.
614    /// The namespace prefix can be defined on the same element as the element or
615    /// attribute in question.
616    ///
617    /// *Unqualified* attribute names do *not* inherit the current *default namespace*.
618    ///
619    /// # Lifetimes
620    ///
621    /// - `'n`: lifetime of an attribute or an element name
622    #[inline]
623    pub fn resolve<'n>(
624        &self,
625        name: QName<'n>,
626        use_default: bool,
627    ) -> (ResolveResult, LocalName<'n>) {
628        let (local_name, prefix) = name.decompose();
629        (self.resolve_prefix(prefix, use_default), local_name)
630    }
631
632    /// Finds a [namespace name] for a given qualified **element name**, borrow
633    /// it from the internal buffer.
634    ///
635    /// Returns `None`, if:
636    /// - name is unqualified
637    /// - prefix not found in the current scope
638    /// - prefix was [unbound] using `xmlns:prefix=""`
639    ///
640    /// [namespace name]: https://www.w3.org/TR/xml-names11/#dt-NSName
641    /// [unbound]: https://www.w3.org/TR/xml-names11/#scoping
642    #[inline]
643    pub fn find(&self, element_name: QName) -> ResolveResult {
644        self.resolve_prefix(element_name.prefix(), true)
645    }
646
647    fn resolve_prefix(&self, prefix: Option<Prefix>, use_default: bool) -> ResolveResult {
648        self.bindings
649            .iter()
650            // Find the last defined binding that corresponds to the given prefix
651            .rev()
652            .find_map(|n| match (n.prefix(&self.buffer), prefix) {
653                // This is default namespace definition and name has no explicit prefix
654                (None, None) if use_default => Some(n.namespace(&self.buffer)),
655                (None, None) => Some(ResolveResult::Unbound),
656
657                // One part has prefix but other is not -> skip
658                (None, Some(_)) => None,
659                (Some(_), None) => None,
660
661                // Prefixes does not match -> skip
662                (Some(definition), Some(usage)) if definition != usage => None,
663
664                // Prefixes the same, entry defines binding reset (corresponds to `xmlns:p=""`)
665                _ if n.value_len == 0 => Some(Self::maybe_unknown(prefix)),
666                // Prefixes the same, returns corresponding namespace
667                _ => Some(n.namespace(&self.buffer)),
668            })
669            .unwrap_or_else(|| Self::maybe_unknown(prefix))
670    }
671
672    #[inline]
673    fn maybe_unknown(prefix: Option<Prefix>) -> ResolveResult<'static> {
674        match prefix {
675            Some(p) => ResolveResult::Unknown(p.into_inner().to_vec()),
676            None => ResolveResult::Unbound,
677        }
678    }
679
680    #[inline]
681    pub const fn iter(&self) -> PrefixIter {
682        PrefixIter {
683            resolver: self,
684            // We initialize the cursor to 2 to skip the two default namespaces xml: and xmlns:
685            bindings_cursor: 2,
686        }
687    }
688}
689
690////////////////////////////////////////////////////////////////////////////////////////////////////
691
692/// Iterator on the current declared prefixes.
693///
694/// See [`NsReader::prefixes`](crate::NsReader::prefixes) for documentation.
695#[derive(Debug, Clone)]
696pub struct PrefixIter<'a> {
697    resolver: &'a NamespaceResolver,
698    bindings_cursor: usize,
699}
700
701impl<'a> Iterator for PrefixIter<'a> {
702    type Item = (PrefixDeclaration<'a>, Namespace<'a>);
703
704    fn next(&mut self) -> Option<(PrefixDeclaration<'a>, Namespace<'a>)> {
705        while let Some(namespace_entry) = self.resolver.bindings.get(self.bindings_cursor) {
706            self.bindings_cursor += 1; // We increment for next read
707
708            // We check if the key has not been overridden by having a look
709            // at the namespaces declared after in the array
710            let prefix = namespace_entry.prefix(&self.resolver.buffer);
711            if self.resolver.bindings[self.bindings_cursor..]
712                .iter()
713                .any(|ne| prefix == ne.prefix(&self.resolver.buffer))
714            {
715                continue; // Overridden
716            }
717            let namespace = if let ResolveResult::Bound(namespace) =
718                namespace_entry.namespace(&self.resolver.buffer)
719            {
720                namespace
721            } else {
722                continue; // We don't return unbound namespaces
723            };
724            let prefix = if let Some(Prefix(prefix)) = prefix {
725                PrefixDeclaration::Named(prefix)
726            } else {
727                PrefixDeclaration::Default
728            };
729            return Some((prefix, namespace));
730        }
731        None // We have exhausted the array
732    }
733
734    fn size_hint(&self) -> (usize, Option<usize>) {
735        // Real count could be less if some namespaces was overridden
736        (0, Some(self.resolver.bindings.len() - self.bindings_cursor))
737    }
738}
739
740#[cfg(test)]
741mod namespaces {
742    use super::*;
743    use pretty_assertions::assert_eq;
744    use ResolveResult::*;
745
746    /// Unprefixed attribute names (resolved with `false` flag) never have a namespace
747    /// according to <https://www.w3.org/TR/xml-names11/#defaulting>:
748    ///
749    /// > A default namespace declaration applies to all unprefixed element names
750    /// > within its scope. Default namespace declarations do not apply directly
751    /// > to attribute names; the interpretation of unprefixed attributes is
752    /// > determined by the element on which they appear.
753    mod unprefixed {
754        use super::*;
755        use pretty_assertions::assert_eq;
756
757        /// Basic tests that checks that basic resolver functionality is working
758        #[test]
759        fn basic() {
760            let name = QName(b"simple");
761            let ns = Namespace(b"default");
762
763            let mut resolver = NamespaceResolver::default();
764            let s = resolver.buffer.len();
765
766            resolver
767                .push(&BytesStart::from_content(" xmlns='default'", 0))
768                .unwrap();
769            assert_eq!(&resolver.buffer[s..], b"default");
770
771            // Check that tags without namespaces does not change result
772            resolver.push(&BytesStart::from_content("", 0)).unwrap();
773            assert_eq!(&resolver.buffer[s..], b"default");
774            resolver.pop();
775
776            assert_eq!(&resolver.buffer[s..], b"default");
777            assert_eq!(
778                resolver.resolve(name, true),
779                (Bound(ns), LocalName(b"simple"))
780            );
781            assert_eq!(
782                resolver.resolve(name, false),
783                (Unbound, LocalName(b"simple"))
784            );
785            assert_eq!(resolver.find(name), Bound(ns));
786        }
787
788        /// Test adding a second level of namespaces, which replaces the previous binding
789        #[test]
790        fn override_namespace() {
791            let name = QName(b"simple");
792            let old_ns = Namespace(b"old");
793            let new_ns = Namespace(b"new");
794
795            let mut resolver = NamespaceResolver::default();
796            let s = resolver.buffer.len();
797
798            resolver
799                .push(&BytesStart::from_content(" xmlns='old'", 0))
800                .unwrap();
801            resolver
802                .push(&BytesStart::from_content(" xmlns='new'", 0))
803                .unwrap();
804
805            assert_eq!(&resolver.buffer[s..], b"oldnew");
806            assert_eq!(
807                resolver.resolve(name, true),
808                (Bound(new_ns), LocalName(b"simple"))
809            );
810            assert_eq!(
811                resolver.resolve(name, false),
812                (Unbound, LocalName(b"simple"))
813            );
814            assert_eq!(resolver.find(name), Bound(new_ns));
815
816            resolver.pop();
817            assert_eq!(&resolver.buffer[s..], b"old");
818            assert_eq!(
819                resolver.resolve(name, true),
820                (Bound(old_ns), LocalName(b"simple"))
821            );
822            assert_eq!(
823                resolver.resolve(name, false),
824                (Unbound, LocalName(b"simple"))
825            );
826            assert_eq!(resolver.find(name), Bound(old_ns));
827        }
828
829        /// Test adding a second level of namespaces, which reset the previous binding
830        /// to not bound state by specifying an empty namespace name.
831        ///
832        /// See <https://www.w3.org/TR/xml-names11/#scoping>
833        #[test]
834        fn reset() {
835            let name = QName(b"simple");
836            let old_ns = Namespace(b"old");
837
838            let mut resolver = NamespaceResolver::default();
839            let s = resolver.buffer.len();
840
841            resolver
842                .push(&BytesStart::from_content(" xmlns='old'", 0))
843                .unwrap();
844            resolver
845                .push(&BytesStart::from_content(" xmlns=''", 0))
846                .unwrap();
847
848            assert_eq!(&resolver.buffer[s..], b"old");
849            assert_eq!(
850                resolver.resolve(name, true),
851                (Unbound, LocalName(b"simple"))
852            );
853            assert_eq!(
854                resolver.resolve(name, false),
855                (Unbound, LocalName(b"simple"))
856            );
857            assert_eq!(resolver.find(name), Unbound);
858
859            resolver.pop();
860            assert_eq!(&resolver.buffer[s..], b"old");
861            assert_eq!(
862                resolver.resolve(name, true),
863                (Bound(old_ns), LocalName(b"simple"))
864            );
865            assert_eq!(
866                resolver.resolve(name, false),
867                (Unbound, LocalName(b"simple"))
868            );
869            assert_eq!(resolver.find(name), Bound(old_ns));
870        }
871    }
872
873    mod declared_prefix {
874        use super::*;
875        use pretty_assertions::assert_eq;
876
877        /// Basic tests that checks that basic resolver functionality is working
878        #[test]
879        fn basic() {
880            let name = QName(b"p:with-declared-prefix");
881            let ns = Namespace(b"default");
882
883            let mut resolver = NamespaceResolver::default();
884            let s = resolver.buffer.len();
885
886            resolver
887                .push(&BytesStart::from_content(" xmlns:p='default'", 0))
888                .unwrap();
889            assert_eq!(&resolver.buffer[s..], b"pdefault");
890
891            // Check that tags without namespaces does not change result
892            resolver.push(&BytesStart::from_content("", 0)).unwrap();
893            assert_eq!(&resolver.buffer[s..], b"pdefault");
894            resolver.pop();
895
896            assert_eq!(&resolver.buffer[s..], b"pdefault");
897            assert_eq!(
898                resolver.resolve(name, true),
899                (Bound(ns), LocalName(b"with-declared-prefix"))
900            );
901            assert_eq!(
902                resolver.resolve(name, false),
903                (Bound(ns), LocalName(b"with-declared-prefix"))
904            );
905            assert_eq!(resolver.find(name), Bound(ns));
906        }
907
908        /// Test adding a second level of namespaces, which replaces the previous binding
909        #[test]
910        fn override_namespace() {
911            let name = QName(b"p:with-declared-prefix");
912            let old_ns = Namespace(b"old");
913            let new_ns = Namespace(b"new");
914
915            let mut resolver = NamespaceResolver::default();
916            let s = resolver.buffer.len();
917
918            resolver
919                .push(&BytesStart::from_content(" xmlns:p='old'", 0))
920                .unwrap();
921            resolver
922                .push(&BytesStart::from_content(" xmlns:p='new'", 0))
923                .unwrap();
924
925            assert_eq!(&resolver.buffer[s..], b"poldpnew");
926            assert_eq!(
927                resolver.resolve(name, true),
928                (Bound(new_ns), LocalName(b"with-declared-prefix"))
929            );
930            assert_eq!(
931                resolver.resolve(name, false),
932                (Bound(new_ns), LocalName(b"with-declared-prefix"))
933            );
934            assert_eq!(resolver.find(name), Bound(new_ns));
935
936            resolver.pop();
937            assert_eq!(&resolver.buffer[s..], b"pold");
938            assert_eq!(
939                resolver.resolve(name, true),
940                (Bound(old_ns), LocalName(b"with-declared-prefix"))
941            );
942            assert_eq!(
943                resolver.resolve(name, false),
944                (Bound(old_ns), LocalName(b"with-declared-prefix"))
945            );
946            assert_eq!(resolver.find(name), Bound(old_ns));
947        }
948
949        /// Test adding a second level of namespaces, which reset the previous binding
950        /// to not bound state by specifying an empty namespace name.
951        ///
952        /// See <https://www.w3.org/TR/xml-names11/#scoping>
953        #[test]
954        fn reset() {
955            let name = QName(b"p:with-declared-prefix");
956            let old_ns = Namespace(b"old");
957
958            let mut resolver = NamespaceResolver::default();
959            let s = resolver.buffer.len();
960
961            resolver
962                .push(&BytesStart::from_content(" xmlns:p='old'", 0))
963                .unwrap();
964            resolver
965                .push(&BytesStart::from_content(" xmlns:p=''", 0))
966                .unwrap();
967
968            assert_eq!(&resolver.buffer[s..], b"poldp");
969            assert_eq!(
970                resolver.resolve(name, true),
971                (Unknown(b"p".to_vec()), LocalName(b"with-declared-prefix"))
972            );
973            assert_eq!(
974                resolver.resolve(name, false),
975                (Unknown(b"p".to_vec()), LocalName(b"with-declared-prefix"))
976            );
977            assert_eq!(resolver.find(name), Unknown(b"p".to_vec()));
978
979            resolver.pop();
980            assert_eq!(&resolver.buffer[s..], b"pold");
981            assert_eq!(
982                resolver.resolve(name, true),
983                (Bound(old_ns), LocalName(b"with-declared-prefix"))
984            );
985            assert_eq!(
986                resolver.resolve(name, false),
987                (Bound(old_ns), LocalName(b"with-declared-prefix"))
988            );
989            assert_eq!(resolver.find(name), Bound(old_ns));
990        }
991    }
992
993    /// Tests for `xml` and `xmlns` built-in prefixes.
994    ///
995    /// See <https://www.w3.org/TR/xml-names11/#xmlReserved>
996    mod builtin_prefixes {
997        use super::*;
998
999        mod xml {
1000            use super::*;
1001            use pretty_assertions::assert_eq;
1002
1003            /// `xml` prefix are always defined, it is not required to define it explicitly.
1004            #[test]
1005            fn undeclared() {
1006                let name = QName(b"xml:random");
1007                let namespace = RESERVED_NAMESPACE_XML.1;
1008
1009                let resolver = NamespaceResolver::default();
1010
1011                assert_eq!(
1012                    resolver.resolve(name, true),
1013                    (Bound(namespace), LocalName(b"random"))
1014                );
1015
1016                assert_eq!(
1017                    resolver.resolve(name, false),
1018                    (Bound(namespace), LocalName(b"random"))
1019                );
1020                assert_eq!(resolver.find(name), Bound(namespace));
1021            }
1022
1023            /// `xml` prefix can be declared but it must be bound to the value
1024            /// `http://www.w3.org/XML/1998/namespace`
1025            #[test]
1026            fn rebound_to_correct_ns() {
1027                let mut resolver = NamespaceResolver::default();
1028                let s = resolver.buffer.len();
1029                resolver.push(
1030                    &BytesStart::from_content(
1031                        " xmlns:xml='http://www.w3.org/XML/1998/namespace'",
1032                        0,
1033                    ),
1034                ).expect("`xml` prefix should be possible to bound to `http://www.w3.org/XML/1998/namespace`");
1035                assert_eq!(&resolver.buffer[s..], b"");
1036            }
1037
1038            /// `xml` prefix cannot be re-declared to another namespace
1039            #[test]
1040            fn rebound_to_incorrect_ns() {
1041                let mut resolver = NamespaceResolver::default();
1042                let s = resolver.buffer.len();
1043                assert_eq!(
1044                    resolver.push(&BytesStart::from_content(
1045                        " xmlns:xml='not_correct_namespace'",
1046                        0,
1047                    )),
1048                    Err(NamespaceError::InvalidXmlPrefixBind(
1049                        b"not_correct_namespace".to_vec()
1050                    )),
1051                );
1052                assert_eq!(&resolver.buffer[s..], b"");
1053            }
1054
1055            /// `xml` prefix cannot be unbound
1056            #[test]
1057            fn unbound() {
1058                let mut resolver = NamespaceResolver::default();
1059                let s = resolver.buffer.len();
1060                assert_eq!(
1061                    resolver.push(&BytesStart::from_content(" xmlns:xml=''", 0)),
1062                    Err(NamespaceError::InvalidXmlPrefixBind(b"".to_vec())),
1063                );
1064                assert_eq!(&resolver.buffer[s..], b"");
1065            }
1066
1067            /// Other prefix cannot be bound to `xml` namespace
1068            #[test]
1069            fn other_prefix_bound_to_xml_namespace() {
1070                let mut resolver = NamespaceResolver::default();
1071                let s = resolver.buffer.len();
1072                assert_eq!(
1073                    resolver.push(&BytesStart::from_content(
1074                        " xmlns:not_xml='http://www.w3.org/XML/1998/namespace'",
1075                        0,
1076                    )),
1077                    Err(NamespaceError::InvalidPrefixForXml(b"not_xml".to_vec())),
1078                );
1079                assert_eq!(&resolver.buffer[s..], b"");
1080            }
1081        }
1082
1083        mod xmlns {
1084            use super::*;
1085            use pretty_assertions::assert_eq;
1086
1087            /// `xmlns` prefix are always defined, it is forbidden to define it explicitly
1088            #[test]
1089            fn undeclared() {
1090                let name = QName(b"xmlns:random");
1091                let namespace = RESERVED_NAMESPACE_XMLNS.1;
1092
1093                let resolver = NamespaceResolver::default();
1094
1095                assert_eq!(
1096                    resolver.resolve(name, true),
1097                    (Bound(namespace), LocalName(b"random"))
1098                );
1099
1100                assert_eq!(
1101                    resolver.resolve(name, false),
1102                    (Bound(namespace), LocalName(b"random"))
1103                );
1104                assert_eq!(resolver.find(name), Bound(namespace));
1105            }
1106
1107            /// `xmlns` prefix cannot be re-declared event to its own namespace
1108            #[test]
1109            fn rebound_to_correct_ns() {
1110                let mut resolver = NamespaceResolver::default();
1111                let s = resolver.buffer.len();
1112                assert_eq!(
1113                    resolver.push(&BytesStart::from_content(
1114                        " xmlns:xmlns='http://www.w3.org/2000/xmlns/'",
1115                        0,
1116                    )),
1117                    Err(NamespaceError::InvalidXmlnsPrefixBind(
1118                        b"http://www.w3.org/2000/xmlns/".to_vec()
1119                    )),
1120                );
1121                assert_eq!(&resolver.buffer[s..], b"");
1122            }
1123
1124            /// `xmlns` prefix cannot be re-declared
1125            #[test]
1126            fn rebound_to_incorrect_ns() {
1127                let mut resolver = NamespaceResolver::default();
1128                let s = resolver.buffer.len();
1129                assert_eq!(
1130                    resolver.push(&BytesStart::from_content(
1131                        " xmlns:xmlns='not_correct_namespace'",
1132                        0,
1133                    )),
1134                    Err(NamespaceError::InvalidXmlnsPrefixBind(
1135                        b"not_correct_namespace".to_vec()
1136                    )),
1137                );
1138                assert_eq!(&resolver.buffer[s..], b"");
1139            }
1140
1141            /// `xmlns` prefix cannot be unbound
1142            #[test]
1143            fn unbound() {
1144                let mut resolver = NamespaceResolver::default();
1145                let s = resolver.buffer.len();
1146                assert_eq!(
1147                    resolver.push(&BytesStart::from_content(" xmlns:xmlns=''", 0)),
1148                    Err(NamespaceError::InvalidXmlnsPrefixBind(b"".to_vec())),
1149                );
1150                assert_eq!(&resolver.buffer[s..], b"");
1151            }
1152
1153            /// Other prefix cannot be bound to `xmlns` namespace
1154            #[test]
1155            fn other_prefix_bound_to_xmlns_namespace() {
1156                let mut resolver = NamespaceResolver::default();
1157                let s = resolver.buffer.len();
1158                assert_eq!(
1159                    resolver.push(&BytesStart::from_content(
1160                        " xmlns:not_xmlns='http://www.w3.org/2000/xmlns/'",
1161                        0,
1162                    )),
1163                    Err(NamespaceError::InvalidPrefixForXmlns(b"not_xmlns".to_vec())),
1164                );
1165                assert_eq!(&resolver.buffer[s..], b"");
1166            }
1167        }
1168    }
1169
1170    #[test]
1171    fn undeclared_prefix() {
1172        let name = QName(b"unknown:prefix");
1173
1174        let resolver = NamespaceResolver::default();
1175
1176        assert_eq!(
1177            resolver.buffer,
1178            b"xmlhttp://www.w3.org/XML/1998/namespacexmlnshttp://www.w3.org/2000/xmlns/"
1179        );
1180        assert_eq!(
1181            resolver.resolve(name, true),
1182            (Unknown(b"unknown".to_vec()), LocalName(b"prefix"))
1183        );
1184        assert_eq!(
1185            resolver.resolve(name, false),
1186            (Unknown(b"unknown".to_vec()), LocalName(b"prefix"))
1187        );
1188        assert_eq!(resolver.find(name), Unknown(b"unknown".to_vec()));
1189    }
1190
1191    /// Checks how the QName is decomposed to a prefix and a local name
1192    #[test]
1193    fn prefix_and_local_name() {
1194        let name = QName(b"foo:bus");
1195        assert_eq!(name.prefix(), Some(Prefix(b"foo")));
1196        assert_eq!(name.local_name(), LocalName(b"bus"));
1197        assert_eq!(name.decompose(), (LocalName(b"bus"), Some(Prefix(b"foo"))));
1198
1199        let name = QName(b"foo:");
1200        assert_eq!(name.prefix(), Some(Prefix(b"foo")));
1201        assert_eq!(name.local_name(), LocalName(b""));
1202        assert_eq!(name.decompose(), (LocalName(b""), Some(Prefix(b"foo"))));
1203
1204        let name = QName(b":foo");
1205        assert_eq!(name.prefix(), Some(Prefix(b"")));
1206        assert_eq!(name.local_name(), LocalName(b"foo"));
1207        assert_eq!(name.decompose(), (LocalName(b"foo"), Some(Prefix(b""))));
1208
1209        let name = QName(b"foo:bus:baz");
1210        assert_eq!(name.prefix(), Some(Prefix(b"foo")));
1211        assert_eq!(name.local_name(), LocalName(b"bus:baz"));
1212        assert_eq!(
1213            name.decompose(),
1214            (LocalName(b"bus:baz"), Some(Prefix(b"foo")))
1215        );
1216    }
1217}