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