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