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