quick_xml/name.rs
1//! Module for handling names according to the W3C [Namespaces in XML 1.1 (Second Edition)][spec]
2//! specification
3//!
4//! [spec]: https://www.w3.org/TR/xml-names11
5
6use crate::events::attributes::Attribute;
7use crate::events::{BytesStart, Event};
8use std::fmt::{self, Debug, Formatter};
9use std::iter::FusedIterator;
10
11/// Some namespace was invalid
12#[derive(Debug, Clone, PartialEq, Eq)]
13pub enum NamespaceError {
14 /// Specified namespace prefix is unknown, cannot resolve namespace for it
15 UnknownPrefix(String),
16 /// Attempts to bind the `xml` prefix to something other than `http://www.w3.org/XML/1998/namespace`.
17 ///
18 /// `xml` prefix can be bound only to `http://www.w3.org/XML/1998/namespace`.
19 ///
20 /// Contains the namespace to which `xml` tried to be bound.
21 InvalidXmlPrefixBind(String),
22 /// Attempts to bind the `xmlns` prefix.
23 ///
24 /// `xmlns` prefix is always bound to `http://www.w3.org/2000/xmlns/` and cannot be bound
25 /// to any other namespace or even to `http://www.w3.org/2000/xmlns/`.
26 ///
27 /// Contains the namespace to which `xmlns` tried to be bound.
28 InvalidXmlnsPrefixBind(String),
29 /// Attempts to bind some prefix (except `xml`) to `http://www.w3.org/XML/1998/namespace`.
30 ///
31 /// Only `xml` prefix can be bound to `http://www.w3.org/XML/1998/namespace`.
32 ///
33 /// Contains the prefix that is tried to be bound.
34 InvalidPrefixForXml(String),
35 /// Attempts to bind some prefix to `http://www.w3.org/2000/xmlns/`.
36 ///
37 /// `http://www.w3.org/2000/xmlns/` cannot be bound to any prefix, even to `xmlns`.
38 ///
39 /// Contains the prefix that is tried to be bound.
40 InvalidPrefixForXmlns(String),
41 /// The total number of `xmlns` / `xmlns:*` namespace bindings in scope exceeded
42 /// the configured [`NamespaceResolver::max_namespace_bindings`] limit. Contains
43 /// the configured limit.
44 ///
45 /// This bounds the work done by [`NamespaceResolver`] (and hence by [`NsReader`](crate::reader::NsReader))
46 /// on untrusted input by capping both the heap allocated and the cost of prefix
47 /// resolution (which scans the binding stack).
48 TooManyBindings(usize),
49 /// The document nested elements more deeply than the namespace resolver's
50 /// depth counter (a `u16`) can track. This bounds stack / scope-bookkeeping
51 /// work on untrusted input. Contains the depth limit that was exceeded.
52 TooDeeplyNested(usize),
53}
54
55impl fmt::Display for NamespaceError {
56 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
57 match self {
58 Self::UnknownPrefix(prefix) => {
59 write!(f, "unknown namespace prefix '{}'", prefix)
60 }
61 Self::InvalidXmlPrefixBind(namespace) => {
62 write!(
63 f,
64 "the namespace prefix 'xml' cannot be bound to '{}'",
65 namespace
66 )
67 }
68 Self::InvalidXmlnsPrefixBind(namespace) => {
69 write!(
70 f,
71 "the namespace prefix 'xmlns' cannot be bound to '{}'",
72 namespace
73 )
74 }
75 Self::InvalidPrefixForXml(prefix) => {
76 write!(
77 f,
78 "the namespace prefix '{}' cannot be bound to 'http://www.w3.org/XML/1998/namespace'",
79 prefix
80 )
81 }
82 Self::InvalidPrefixForXmlns(prefix) => {
83 write!(
84 f,
85 "the namespace prefix '{}' cannot be bound to 'http://www.w3.org/2000/xmlns/'",
86 prefix
87 )
88 }
89 Self::TooManyBindings(limit) => {
90 write!(
91 f,
92 "more than {} namespace bindings in scope; \
93 raise the limit with NamespaceResolver::set_max_namespace_bindings",
94 limit,
95 )
96 }
97 Self::TooDeeplyNested(limit) => {
98 write!(
99 f,
100 "document nests elements deeper than the supported limit of {}",
101 limit
102 )
103 }
104 }
105 }
106}
107
108impl std::error::Error for NamespaceError {}
109
110////////////////////////////////////////////////////////////////////////////////////////////////////
111
112/// A [qualified name] of an element or an attribute, including an optional
113/// namespace [prefix](Prefix) and a [local name](LocalName).
114///
115/// [qualified name]: https://www.w3.org/TR/xml-names11/#dt-qualname
116#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
117#[cfg_attr(feature = "serde-types", derive(serde::Deserialize, serde::Serialize))]
118pub struct QName<'a>(pub &'a str);
119impl<'a> QName<'a> {
120 /// Converts this name to an internal slice representation.
121 #[inline(always)]
122 pub const fn into_inner(self) -> &'a str {
123 self.0
124 }
125
126 /// Returns local part of this qualified name.
127 ///
128 /// All content up to and including the first `:` character is removed from
129 /// the tag name.
130 ///
131 /// # Examples
132 ///
133 /// ```
134 /// # use quick_xml::name::QName;
135 /// let simple = QName("simple-name");
136 /// assert_eq!(simple.local_name().into_inner(), "simple-name");
137 ///
138 /// let qname = QName("namespace:simple-name");
139 /// assert_eq!(qname.local_name().into_inner(), "simple-name");
140 /// ```
141 pub fn local_name(&self) -> LocalName<'a> {
142 LocalName(self.index().map_or(self.0, |i| &self.0[i + 1..]))
143 }
144
145 /// Returns namespace part of this qualified name or `None` if namespace part
146 /// is not defined (symbol `':'` not found).
147 ///
148 /// # Examples
149 ///
150 /// ```
151 /// # use std::convert::AsRef;
152 /// # use quick_xml::name::QName;
153 /// let simple = QName("simple-name");
154 /// assert_eq!(simple.prefix(), None);
155 ///
156 /// let qname = QName("prefix:simple-name");
157 /// assert_eq!(qname.prefix().map(|n| n.into_inner()), Some("prefix"));
158 /// ```
159 pub fn prefix(&self) -> Option<Prefix<'a>> {
160 self.index().map(|i| Prefix(&self.0[..i]))
161 }
162
163 /// The same as `(qname.local_name(), qname.prefix())`, but does only one
164 /// lookup for a `':'` symbol.
165 pub fn decompose(&self) -> (LocalName<'a>, Option<Prefix<'a>>) {
166 match self.index() {
167 None => (LocalName(self.0), None),
168 Some(i) => (LocalName(&self.0[i + 1..]), Some(Prefix(&self.0[..i]))),
169 }
170 }
171
172 /// If that `QName` represents `"xmlns"` series of names, returns `Some`,
173 /// otherwise `None` is returned.
174 ///
175 /// # Examples
176 ///
177 /// ```
178 /// # use quick_xml::name::{QName, PrefixDeclaration};
179 /// let qname = QName("xmlns");
180 /// assert_eq!(qname.as_namespace_binding(), Some(PrefixDeclaration::Default));
181 ///
182 /// let qname = QName("xmlns:prefix");
183 /// assert_eq!(qname.as_namespace_binding(), Some(PrefixDeclaration::Named("prefix")));
184 ///
185 /// // Be aware that this method does not check the validity of the prefix - it can be empty!
186 /// let qname = QName("xmlns:");
187 /// assert_eq!(qname.as_namespace_binding(), Some(PrefixDeclaration::Named("")));
188 ///
189 /// let qname = QName("other-name");
190 /// assert_eq!(qname.as_namespace_binding(), None);
191 ///
192 /// // https://www.w3.org/TR/xml-names11/#xmlReserved
193 /// let qname = QName("xmlns-reserved-name");
194 /// assert_eq!(qname.as_namespace_binding(), None);
195 /// ```
196 pub fn as_namespace_binding(&self) -> Option<PrefixDeclaration<'a>> {
197 if self.0.starts_with("xmlns") {
198 return match self.0.as_bytes().get(5) {
199 None => Some(PrefixDeclaration::Default),
200 Some(&b':') => Some(PrefixDeclaration::Named(&self.0[6..])),
201 _ => None,
202 };
203 }
204 None
205 }
206
207 /// Returns the index in the name where prefix ended
208 #[inline(always)]
209 fn index(&self) -> Option<usize> {
210 self.0.find(':')
211 }
212}
213
214impl<'a> Debug for QName<'a> {
215 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
216 write!(f, "QName({})", self.0)
217 }
218}
219impl<'a> AsRef<str> for QName<'a> {
220 #[inline]
221 fn as_ref(&self) -> &str {
222 self.0
223 }
224}
225
226////////////////////////////////////////////////////////////////////////////////////////////////////
227
228/// A [local (unqualified) name] of an element or an attribute, i.e. a name
229/// without [prefix](Prefix).
230///
231/// [local (unqualified) name]: https://www.w3.org/TR/xml-names11/#dt-localname
232#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
233#[cfg_attr(feature = "serde-types", derive(serde::Deserialize, serde::Serialize))]
234pub struct LocalName<'a>(pub(crate) &'a str);
235impl<'a> LocalName<'a> {
236 /// Converts this name to an internal slice representation.
237 #[inline(always)]
238 pub const fn into_inner(self) -> &'a str {
239 self.0
240 }
241}
242
243impl<'a> Debug for LocalName<'a> {
244 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
245 write!(f, "LocalName({})", self.0)
246 }
247}
248
249impl<'a> AsRef<str> for LocalName<'a> {
250 #[inline]
251 fn as_ref(&self) -> &str {
252 self.0
253 }
254}
255
256impl<'a> From<QName<'a>> for LocalName<'a> {
257 /// Creates `LocalName` from a [`QName`]
258 ///
259 /// # Examples
260 ///
261 /// ```
262 /// # use quick_xml::name::{LocalName, QName};
263 ///
264 /// let local: LocalName = QName("unprefixed").into();
265 /// assert_eq!(local.into_inner(), "unprefixed");
266 ///
267 /// let local: LocalName = QName("some:prefix").into();
268 /// assert_eq!(local.into_inner(), "prefix");
269 /// ```
270 #[inline]
271 fn from(name: QName<'a>) -> Self {
272 Self(name.index().map_or(name.0, |i| &name.0[i + 1..]))
273 }
274}
275
276////////////////////////////////////////////////////////////////////////////////////////////////////
277
278/// A [namespace prefix] part of the [qualified name](QName) of an element tag
279/// or an attribute: a `prefix` in `<prefix:local-element-name>` or
280/// `prefix:local-attribute-name="attribute value"`.
281///
282/// [namespace prefix]: https://www.w3.org/TR/xml-names11/#dt-prefix
283#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
284#[cfg_attr(feature = "serde-types", derive(serde::Deserialize, serde::Serialize))]
285pub struct Prefix<'a>(&'a str);
286impl<'a> Prefix<'a> {
287 /// Extracts internal slice
288 #[inline(always)]
289 pub const fn into_inner(self) -> &'a str {
290 self.0
291 }
292
293 /// Checks if this prefix is a special prefix `xml`.
294 #[inline(always)]
295 pub const fn is_xml(&self) -> bool {
296 matches!(self.0.as_bytes(), b"xml")
297 }
298
299 /// Checks if this prefix is a special prefix `xmlns`.
300 #[inline(always)]
301 pub const fn is_xmlns(&self) -> bool {
302 matches!(self.0.as_bytes(), b"xmlns")
303 }
304}
305
306impl<'a> Debug for Prefix<'a> {
307 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
308 write!(f, "Prefix({})", self.0)
309 }
310}
311
312impl<'a> AsRef<str> for Prefix<'a> {
313 #[inline]
314 fn as_ref(&self) -> &str {
315 self.0
316 }
317}
318
319////////////////////////////////////////////////////////////////////////////////////////////////////
320
321/// A namespace prefix declaration, `xmlns` or `xmlns:<name>`, as defined in
322/// [XML Schema specification](https://www.w3.org/TR/xml-names11/#ns-decl)
323#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
324pub enum PrefixDeclaration<'a> {
325 /// XML attribute binds a default namespace. Corresponds to `xmlns` in `xmlns="..."`
326 Default,
327 /// XML attribute binds a specified prefix to a namespace. Corresponds to a
328 /// `prefix` in `xmlns:prefix="..."`, which is stored as payload of this variant.
329 Named(&'a str),
330}
331
332impl<'a> Debug for PrefixDeclaration<'a> {
333 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
334 match self {
335 Self::Default => f.write_str("PrefixDeclaration::Default"),
336 Self::Named(prefix) => {
337 write!(f, "PrefixDeclaration::Named({})", prefix)
338 }
339 }
340 }
341}
342
343////////////////////////////////////////////////////////////////////////////////////////////////////
344
345/// A [namespace name] that is declared in a `xmlns[:prefix]="namespace name"`.
346///
347/// [namespace name]: https://www.w3.org/TR/xml-names11/#dt-NSName
348#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
349#[cfg_attr(feature = "serde-types", derive(serde::Deserialize, serde::Serialize))]
350pub struct Namespace<'a>(pub &'a str);
351impl<'a> Namespace<'a> {
352 /// Converts this namespace to an internal slice representation.
353 ///
354 /// This is [non-normalized] attribute value, i.e. any entity references is not
355 /// expanded and space characters are not removed. This means, that different
356 /// string slices, returned from this method, can represent the same namespace
357 /// and would be treated by parser as identical.
358 ///
359 /// For example, if the entity **eacute** has been defined to be **é**,
360 /// the empty tags below all contain namespace declarations binding the
361 /// prefix `p` to the same [IRI reference], `http://example.org/rosé`.
362 ///
363 /// ```xml
364 /// <p:foo xmlns:p="http://example.org/rosé" />
365 /// <p:foo xmlns:p="http://example.org/rosé" />
366 /// <p:foo xmlns:p="http://example.org/rosé" />
367 /// <p:foo xmlns:p="http://example.org/rosé" />
368 /// <p:foo xmlns:p="http://example.org/rosé" />
369 /// ```
370 ///
371 /// This is because XML entity references are expanded during attribute value
372 /// normalization.
373 ///
374 /// [non-normalized]: https://www.w3.org/TR/xml11/#AVNormalize
375 /// [IRI reference]: https://datatracker.ietf.org/doc/html/rfc3987
376 #[inline(always)]
377 pub const fn into_inner(self) -> &'a str {
378 self.0
379 }
380 //TODO: implement value normalization and use it when comparing namespaces
381}
382
383impl<'a> Debug for Namespace<'a> {
384 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
385 write!(f, "Namespace({})", self.0)
386 }
387}
388
389impl<'a> AsRef<str> for Namespace<'a> {
390 #[inline]
391 fn as_ref(&self) -> &str {
392 self.0
393 }
394}
395
396////////////////////////////////////////////////////////////////////////////////////////////////////
397
398/// Result of [prefix] resolution which creates by [`NamespaceResolver::resolve`],
399/// [`NsReader::read_resolved_event`] and
400/// [`NsReader::read_resolved_event_into`] methods.
401///
402/// [prefix]: Prefix
403/// [`NsReader::read_resolved_event`]: crate::reader::NsReader::read_resolved_event
404/// [`NsReader::read_resolved_event_into`]: crate::reader::NsReader::read_resolved_event_into
405#[derive(Clone, PartialEq, Eq, Hash)]
406pub enum ResolveResult<'ns> {
407 /// Qualified name does not contain prefix, and resolver does not define
408 /// default namespace, so name is not bound to any namespace
409 Unbound,
410 /// [`Prefix`] resolved to the specified namespace
411 Bound(Namespace<'ns>),
412 /// Specified prefix was not found in scope
413 Unknown(String),
414}
415
416impl<'ns> Debug for ResolveResult<'ns> {
417 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
418 match self {
419 Self::Unbound => write!(f, "Unbound"),
420 Self::Bound(ns) => write!(f, "Bound({:?})", ns),
421 Self::Unknown(p) => write!(f, "Unknown({})", p),
422 }
423 }
424}
425
426impl<'ns> TryFrom<ResolveResult<'ns>> for Option<Namespace<'ns>> {
427 type Error = NamespaceError;
428
429 /// Try to convert this result to an optional namespace and returns
430 /// [`NamespaceError::UnknownPrefix`] if this result represents unknown prefix
431 fn try_from(result: ResolveResult<'ns>) -> Result<Self, NamespaceError> {
432 use ResolveResult::*;
433
434 match result {
435 Unbound => Ok(None),
436 Bound(ns) => Ok(Some(ns)),
437 Unknown(p) => Err(NamespaceError::UnknownPrefix(p)),
438 }
439 }
440}
441
442////////////////////////////////////////////////////////////////////////////////////////////////////
443
444/// An entry that contains index into the buffer with namespace bindings.
445///
446/// Defines a mapping from *[namespace prefix]* to *[namespace name]*.
447/// If prefix is empty, defines a *default namespace* binding that applies to
448/// unprefixed element names (unprefixed attribute names do not bind to any
449/// namespace and they processing is dependent on the element in which their
450/// defined).
451///
452/// [namespace prefix]: https://www.w3.org/TR/xml-names11/#dt-prefix
453/// [namespace name]: https://www.w3.org/TR/xml-names11/#dt-NSName
454#[derive(Debug, Clone)]
455struct NamespaceBinding {
456 /// Index of the namespace in the buffer
457 start: usize,
458 /// Length of the prefix
459 /// * if greater than zero, then binds this namespace to the slice
460 /// `[start..start + prefix_len]` in the buffer.
461 /// * else defines the current default namespace.
462 prefix_len: usize,
463 /// The length of a namespace name (the URI) of this namespace declaration.
464 /// Name started just after prefix and extend for `value_len` bytes.
465 ///
466 /// The XML standard [specifies] that an empty namespace value 'removes' a namespace declaration
467 /// for the extent of its scope. For prefix declarations that's not very interesting, but it is
468 /// vital for default namespace declarations. With `xmlns=""` you can revert back to the default
469 /// behaviour of leaving unqualified element names unqualified.
470 ///
471 /// [specifies]: https://www.w3.org/TR/xml-names11/#scoping
472 value_len: usize,
473 /// Level of nesting at which this namespace was declared. The declaring element is included,
474 /// i.e., a declaration on the document root has `level = 1`.
475 /// This is used to pop the namespace when the element gets closed.
476 level: u16,
477}
478
479impl NamespaceBinding {
480 /// Get the namespace prefix, bound to this namespace declaration, or `None`,
481 /// if this declaration is for default namespace (`xmlns="..."`).
482 #[inline]
483 const fn prefix<'b>(&self, ns_buffer: &'b str) -> Option<Prefix<'b>> {
484 if self.prefix_len == 0 {
485 None
486 } else {
487 // We use split_at to get [start..start + prefix_len]
488 // in a constant way
489 let (_, prefix) = ns_buffer.split_at(self.start);
490 let (prefix, _) = prefix.split_at(self.prefix_len);
491 Some(Prefix(prefix))
492 }
493 }
494
495 /// Gets the namespace name (the URI) slice out of namespace buffer
496 ///
497 /// Returns `None` if namespace for this prefix was explicitly removed from
498 /// scope, using `xmlns[:prefix]=""`
499 #[inline]
500 const fn namespace<'ns>(&self, buffer: &'ns str) -> ResolveResult<'ns> {
501 if self.value_len == 0 {
502 ResolveResult::Unbound
503 } else {
504 // We use split_at to get [start + prefix_len..start + prefix_len + value_len]
505 // in a constant way
506 let (_, ns) = buffer.split_at(self.start + self.prefix_len);
507 let (ns, _) = ns.split_at(self.value_len);
508 ResolveResult::Bound(Namespace(ns))
509 }
510 }
511}
512
513/// A storage for currently defined namespace bindings, which is used to resolve
514/// prefixes into namespaces.
515///
516/// Holds all internal logic to push/pop namespaces with their levels.
517#[derive(Clone, Debug)]
518pub struct NamespaceResolver {
519 /// Buffer that contains names of namespace prefixes (the part between `xmlns:`
520 /// and an `=`) and namespace values.
521 buffer: String,
522 /// A stack of namespace bindings to prefixes that currently in scope
523 bindings: Vec<NamespaceBinding>,
524 /// The number of open tags at the moment. We need to keep track of this to know which namespace
525 /// declarations to remove when we encounter an `End` event.
526 nesting_level: u16,
527 /// Maximum number of user-declared `xmlns` / `xmlns:*` namespace bindings
528 /// allowed in scope at once, not counting the two reserved bindings for
529 /// `xml` and `xmlns`. See [`set_max_namespace_bindings`](Self::set_max_namespace_bindings).
530 max_namespace_bindings: usize,
531}
532
533/// Default limit on the number of `xmlns` / `xmlns:*` namespace bindings allowed in scope at
534/// once in a [`NamespaceResolver`], not counting the two reserved bindings (`xml` and `xmlns`)
535/// that are always present.
536///
537/// Real-world XML dialects (XHTML, SVG, SOAP, RSS, RRDP, ...) declare a handful of namespaces,
538/// almost always on the root element; 128 is significantly more than what most legitimate documents
539/// would declare, while bounding both the heap allocated and the cost of prefix resolution
540/// (which scans the binding stack).
541pub const DEFAULT_MAX_NAMESPACE_BINDINGS: usize = 128;
542
543/// The number of namespace bindings pre-loaded by [`NamespaceResolver::default()`]
544/// (`xml` and `xmlns`). Subtracted from `bindings.len()` when checking against
545/// the user-facing [`max_namespace_bindings`](NamespaceResolver::max_namespace_bindings)
546/// limit, so these built-in bindings don't count against the user's limit.
547const BUILTIN_NAMESPACE_BINDINGS: usize = 2;
548
549/// This constant defines one the of [reserved namespaces] for the xml standard.
550///
551/// The prefix `xml` is by definition bound to the namespace name
552/// `http://www.w3.org/XML/1998/namespace`. It may, but need not, be declared, and must not be
553/// undeclared or bound to any other namespace name. Other prefixes must not be bound to this
554/// namespace name, and it must not be declared as the default namespace.
555///
556/// [reserved namespaces]: https://www.w3.org/TR/xml-names11/#xmlReserved
557const RESERVED_NAMESPACE_XML: (Prefix, Namespace) = (
558 Prefix("xml"),
559 Namespace("http://www.w3.org/XML/1998/namespace"),
560);
561/// This constant defines one of the [reserved namespaces] for the xml standard.
562///
563/// The prefix `xmlns` is used only to declare namespace bindings and is by definition bound
564/// to the namespace name `http://www.w3.org/2000/xmlns/`. It must not be declared or
565/// undeclared. Other prefixes must not be bound to this namespace name, and it must not be
566/// declared as the default namespace. Element names must not have the prefix `xmlns`.
567///
568/// [reserved namespaces]: https://www.w3.org/TR/xml-names11/#xmlReserved
569const RESERVED_NAMESPACE_XMLNS: (Prefix, Namespace) =
570 (Prefix("xmlns"), Namespace("http://www.w3.org/2000/xmlns/"));
571
572impl Default for NamespaceResolver {
573 fn default() -> Self {
574 let mut buffer = String::new();
575 let mut bindings = Vec::new();
576 for ent in &[RESERVED_NAMESPACE_XML, RESERVED_NAMESPACE_XMLNS] {
577 let prefix = ent.0.into_inner();
578 let uri = ent.1.into_inner();
579 bindings.push(NamespaceBinding {
580 start: buffer.len(),
581 prefix_len: prefix.len(),
582 value_len: uri.len(),
583 level: 0,
584 });
585 buffer.push_str(prefix);
586 buffer.push_str(uri);
587 }
588
589 Self {
590 buffer,
591 bindings,
592 nesting_level: 0,
593 max_namespace_bindings: DEFAULT_MAX_NAMESPACE_BINDINGS,
594 }
595 }
596}
597
598impl NamespaceResolver {
599 /// Adds new binding of prefix to namespace, returns the result of operation.
600 ///
601 /// Binding will be added on current nesting level and will be removed, when
602 /// level will be [popped out].
603 ///
604 /// The operation may fail if you try to (re-)declare reserved prefixes `xml` and `xmlns`.
605 ///
606 /// Note, that method does not check if namespace was already added on that level.
607 /// Use `resolver.bindings_of(resolver.level()).any()` if you want to check that.
608 /// New definition will be added and replace the old.
609 ///
610 /// Implementation detail: memory occupied by old binding of that level still will be used.
611 ///
612 /// ```
613 /// # use pretty_assertions::assert_eq;
614 /// # use quick_xml::name::{Namespace, NamespaceResolver, PrefixDeclaration, QName, ResolveResult};
615 /// #
616 /// let mut resolver = NamespaceResolver::default();
617 /// // names without prefix are unbound by default
618 /// assert_eq!(
619 /// resolver.resolve_element(QName("name")).0,
620 /// ResolveResult::Unbound,
621 /// );
622 /// // names with undeclared prefix are unknown
623 /// assert_eq!(
624 /// resolver.resolve_element(QName("ns:name")).0,
625 /// ResolveResult::Unknown("ns".to_string()),
626 /// );
627 ///
628 /// resolver.add(PrefixDeclaration::Default, Namespace("example.com"));
629 /// resolver.add(PrefixDeclaration::Named("ns"), Namespace("my:namespace"));
630 ///
631 /// assert_eq!(
632 /// resolver.resolve_element(QName("name")).0,
633 /// ResolveResult::Bound(Namespace("example.com")),
634 /// );
635 /// assert_eq!(
636 /// resolver.resolve_element(QName("ns:name")).0,
637 /// ResolveResult::Bound(Namespace("my:namespace")),
638 /// );
639 ///
640 /// // adding empty namespace clears the binding
641 /// resolver.add(PrefixDeclaration::Default, Namespace(""));
642 /// resolver.add(PrefixDeclaration::Named("ns"), Namespace(""));
643 ///
644 /// assert_eq!(
645 /// resolver.resolve_element(QName("name")).0,
646 /// ResolveResult::Unbound,
647 /// );
648 /// assert_eq!(
649 /// resolver.resolve_element(QName("ns:name")).0,
650 /// ResolveResult::Unknown("ns".to_string()),
651 /// );
652 /// ```
653 /// [popped out]: Self::pop
654 pub fn add(
655 &mut self,
656 prefix: PrefixDeclaration,
657 namespace: Namespace,
658 ) -> Result<(), NamespaceError> {
659 let level = self.nesting_level;
660 match prefix {
661 PrefixDeclaration::Default => {
662 if self
663 .bindings
664 .len()
665 .saturating_sub(BUILTIN_NAMESPACE_BINDINGS)
666 >= self.max_namespace_bindings
667 {
668 return Err(NamespaceError::TooManyBindings(self.max_namespace_bindings));
669 }
670 let start = self.buffer.len();
671 self.buffer.push_str(namespace.0);
672 self.bindings.push(NamespaceBinding {
673 start,
674 prefix_len: 0,
675 value_len: namespace.0.len(),
676 level,
677 });
678 }
679 PrefixDeclaration::Named("xml") => {
680 if namespace != RESERVED_NAMESPACE_XML.1 {
681 // error, `xml` prefix explicitly set to different value
682 return Err(NamespaceError::InvalidXmlPrefixBind(
683 namespace.0.to_string(),
684 ));
685 }
686 // don't add another NamespaceEntry for the `xml` namespace prefix
687 }
688 PrefixDeclaration::Named("xmlns") => {
689 // error, `xmlns` prefix explicitly set
690 return Err(NamespaceError::InvalidXmlnsPrefixBind(
691 namespace.0.to_string(),
692 ));
693 }
694 PrefixDeclaration::Named(prefix) => {
695 if namespace == RESERVED_NAMESPACE_XML.1 {
696 // error, non-`xml` prefix set to xml uri
697 return Err(NamespaceError::InvalidPrefixForXml(prefix.to_string()));
698 } else if namespace == RESERVED_NAMESPACE_XMLNS.1 {
699 // error, non-`xmlns` prefix set to xmlns uri
700 return Err(NamespaceError::InvalidPrefixForXmlns(prefix.to_string()));
701 }
702
703 if self
704 .bindings
705 .len()
706 .saturating_sub(BUILTIN_NAMESPACE_BINDINGS)
707 >= self.max_namespace_bindings
708 {
709 return Err(NamespaceError::TooManyBindings(self.max_namespace_bindings));
710 }
711 let start = self.buffer.len();
712 self.buffer.push_str(prefix);
713 self.buffer.push_str(namespace.0);
714 self.bindings.push(NamespaceBinding {
715 start,
716 prefix_len: prefix.len(),
717 value_len: namespace.0.len(),
718 level,
719 });
720 }
721 }
722 Ok(())
723 }
724
725 /// Begins a new scope and add to it all [namespace bindings] that found in
726 /// the specified start element.
727 ///
728 /// [namespace bindings]: https://www.w3.org/TR/xml-names11/#dt-NSDecl
729 pub fn push(&mut self, start: &BytesStart) -> Result<(), NamespaceError> {
730 self.nesting_level = self
731 .nesting_level
732 .checked_add(1)
733 .ok_or(NamespaceError::TooDeeplyNested(u16::MAX as usize))?;
734 // adds new namespaces for attributes starting with 'xmlns:' and for the 'xmlns'
735 // (default namespace) attribute.
736 for a in start.attributes().with_checks(false) {
737 if let Ok(Attribute { key: k, value: v }) = a {
738 if let Some(prefix) = k.as_namespace_binding() {
739 self.add(prefix, Namespace(&v))?;
740 }
741 } else {
742 break;
743 }
744 }
745 Ok(())
746 }
747
748 /// Returns the maximum number of user-declared `xmlns` / `xmlns:*` namespace
749 /// bindings allowed in scope at once (not counting the two reserved bindings
750 /// for `xml` and `xmlns`).
751 ///
752 /// Defaults to [`DEFAULT_MAX_NAMESPACE_BINDINGS`].
753 #[inline]
754 pub const fn max_namespace_bindings(&self) -> usize {
755 self.max_namespace_bindings
756 }
757
758 /// Sets the maximum number of user-declared `xmlns` / `xmlns:*` namespace bindings
759 /// allowed in scope at once. The two reserved bindings (`xml` and `xmlns`) do not
760 /// count toward this limit.
761 ///
762 /// [`add`](Self::add) is called by [`push`](Self::push), which is called by
763 /// [`NsReader`](crate::reader::NsReader) for every `Start`/`Empty` event *before* the event
764 /// is returned to the caller. This limit bounds both the heap allocated for namespace
765 /// bindings and the cost of prefix resolution (which scans the binding stack). See
766 /// <https://github.com/tafia/quick-xml/issues/970> and <https://github.com/tafia/quick-xml/issues/980>.
767 ///
768 /// Pass `usize::MAX` to disable the limit.
769 #[inline]
770 pub fn set_max_namespace_bindings(&mut self, limit: usize) -> &mut Self {
771 self.max_namespace_bindings = limit;
772 self
773 }
774
775 /// Ends a top-most scope by popping all [namespace bindings], that was added by
776 /// last call to [`Self::push()`] and [`Self::add()`].
777 ///
778 /// [namespace bindings]: https://www.w3.org/TR/xml-names11/#dt-NSDecl
779 #[inline]
780 pub fn pop(&mut self) {
781 self.set_level(self.nesting_level.saturating_sub(1));
782 }
783
784 /// Runs action as if all namespaces from the specified `start` element were added
785 /// to the resolver, but without actually changing the resolver state.
786 pub fn with<F, R>(&mut self, start: &BytesStart, mut action: F) -> Result<R, NamespaceError>
787 where
788 F: FnMut(&Self) -> R,
789 {
790 self.push(start)?;
791 let result = action(self);
792 self.pop();
793 Ok(result)
794 }
795
796 /// Sets new number of [`push`] calls that were not followed by [`pop`] calls.
797 ///
798 /// When set to value lesser than current [`level`], behaves as if [`pop`]
799 /// will be called until the level reaches the corresponding value.
800 ///
801 /// When set to value bigger than current [`level`] just increases internal
802 /// counter. You may need to call [`pop`] more times that required before.
803 ///
804 /// # Example
805 ///
806 /// ```
807 /// # use pretty_assertions::assert_eq;
808 /// # use quick_xml::events::BytesStart;
809 /// # use quick_xml::name::{Namespace, NamespaceResolver, PrefixDeclaration, QName, ResolveResult};
810 /// #
811 /// let mut resolver = NamespaceResolver::default();
812 ///
813 /// assert_eq!(resolver.level(), 0);
814 ///
815 /// resolver.push(&BytesStart::new("tag"));
816 /// assert_eq!(resolver.level(), 1);
817 ///
818 /// resolver.set_level(10);
819 /// assert_eq!(resolver.level(), 10);
820 ///
821 /// resolver.pop();
822 /// assert_eq!(resolver.level(), 9);
823 ///
824 /// resolver.set_level(0);
825 /// assert_eq!(resolver.level(), 0);
826 ///
827 /// // pop from empty resolver does nothing
828 /// resolver.pop();
829 /// assert_eq!(resolver.level(), 0);
830 /// ```
831 ///
832 /// [`push`]: Self::push
833 /// [`pop`]: Self::pop
834 /// [`level`]: Self::level
835 pub fn set_level(&mut self, level: u16) {
836 self.nesting_level = level;
837 // from the back (most deeply nested scope), look for the first scope that is still valid
838 match self.bindings.iter().rposition(|n| n.level <= level) {
839 // none of the namespaces are valid, remove all of them
840 None => {
841 self.buffer.clear();
842 self.bindings.clear();
843 }
844 // drop all namespaces past the last valid namespace
845 Some(last_valid_pos) => {
846 if let Some(len) = self.bindings.get(last_valid_pos + 1).map(|n| n.start) {
847 self.buffer.truncate(len);
848 self.bindings.truncate(last_valid_pos + 1);
849 }
850 }
851 }
852 }
853
854 /// Resolves a potentially qualified **element name** or **attribute name**
855 /// into _(namespace name, local name)_.
856 ///
857 /// _Qualified_ names have the form `local-name` or `prefix:local-name` where the `prefix`
858 /// is defined on any containing XML element via `xmlns:prefix="the:namespace:uri"`.
859 /// The namespace prefix can be defined on the same element as the name in question.
860 ///
861 /// The method returns following results depending on the `name` shape, `attribute` flag
862 /// and the presence of the default namespace on element or any of its parents:
863 ///
864 /// |use_default|`xmlns="..."`|QName |ResolveResult |LocalName
865 /// |-----------|-------------|-------------------|-----------------------|------------
866 /// |`false` |_(any)_ |`local-name` |[`Unbound`] |`local-name`
867 /// |`false` |_(any)_ |`prefix:local-name`|[`Bound`] / [`Unknown`]|`local-name`
868 /// |`true` |Not defined |`local-name` |[`Unbound`] |`local-name`
869 /// |`true` |Defined |`local-name` |[`Bound`] (to `xmlns`) |`local-name`
870 /// |`true` |_(any)_ |`prefix:local-name`|[`Bound`] / [`Unknown`]|`local-name`
871 ///
872 /// # Parameters
873 /// - `name`: probably qualified name to resolve;
874 /// - `use_default`: whether to try to translate `None` prefix to the currently default namespace
875 /// (bound using `xmlns="default namespace"`) or return [`ResolveResult::Unbound`].
876 /// For attribute names this should be set to `false` and for element names to `true`.
877 ///
878 /// # Lifetimes
879 ///
880 /// - `'n`: lifetime of a name. Returned local name will be bound to the same
881 /// lifetime as the name in question.
882 /// - returned namespace name will be bound to the resolver itself
883 ///
884 /// [`Bound`]: ResolveResult::Bound
885 /// [`Unbound`]: ResolveResult::Unbound
886 /// [`Unknown`]: ResolveResult::Unknown
887 #[inline]
888 pub fn resolve<'n>(
889 &self,
890 name: QName<'n>,
891 use_default: bool,
892 ) -> (ResolveResult<'_>, LocalName<'n>) {
893 let (local_name, prefix) = name.decompose();
894 (self.resolve_prefix(prefix, use_default), local_name)
895 }
896
897 /// Convenient method to call `resolve(name, true)`. May be used to clearly
898 /// express that we want to resolve an element name, and not an attribute name.
899 #[inline]
900 pub fn resolve_element<'n>(&self, name: QName<'n>) -> (ResolveResult<'_>, LocalName<'n>) {
901 self.resolve(name, true)
902 }
903
904 /// Convenient method to call `resolve(name, false)`. May be used to clearly
905 /// express that we want to resolve an attribute name, and not an element name.
906 #[inline]
907 pub fn resolve_attribute<'n>(&self, name: QName<'n>) -> (ResolveResult<'_>, LocalName<'n>) {
908 self.resolve(name, false)
909 }
910
911 /// Finds a [namespace name] for a given event, if applicable.
912 ///
913 /// Namespace is resolved only for [`Start`], [`Empty`] and [`End`] events.
914 /// For all other events the concept of namespace is not defined, so
915 /// a [`ResolveResult::Unbound`] is returned.
916 ///
917 /// # Examples
918 ///
919 /// ```
920 /// # use pretty_assertions::assert_eq;
921 /// use quick_xml::events::Event;
922 /// use quick_xml::name::{Namespace, QName, ResolveResult::*};
923 /// use quick_xml::reader::NsReader;
924 ///
925 /// let mut reader = NsReader::from_str(r#"
926 /// <x:tag1 xmlns:x="www.xxxx" xmlns:y="www.yyyy" att1 = "test">
927 /// <y:tag2><!--Test comment-->Test</y:tag2>
928 /// <y:tag2>Test 2</y:tag2>
929 /// </x:tag1>
930 /// "#);
931 /// reader.config_mut().trim_text(true);
932 ///
933 /// let mut count = 0;
934 /// let mut txt = Vec::new();
935 /// loop {
936 /// let event = reader.read_event().unwrap();
937 /// match reader.resolver().resolve_event(event) {
938 /// (Bound(Namespace("www.xxxx")), Event::Start(e)) => {
939 /// count += 1;
940 /// assert_eq!(e.local_name(), QName("tag1").into());
941 /// }
942 /// (Bound(Namespace("www.yyyy")), Event::Start(e)) => {
943 /// count += 1;
944 /// assert_eq!(e.local_name(), QName("tag2").into());
945 /// }
946 /// (_, Event::Start(_)) => unreachable!(),
947 ///
948 /// (_, Event::Text(e)) => {
949 /// txt.push(e.into_inner().into_owned())
950 /// }
951 /// (_, Event::Eof) => break,
952 /// _ => (),
953 /// }
954 /// }
955 /// assert_eq!(count, 3);
956 /// assert_eq!(txt, vec!["Test".to_string(), "Test 2".to_string()]);
957 /// ```
958 ///
959 /// [namespace name]: https://www.w3.org/TR/xml-names11/#dt-NSName
960 /// [`Empty`]: Event::Empty
961 /// [`Start`]: Event::Start
962 /// [`End`]: Event::End
963 pub fn resolve_event<'i>(&self, event: Event<'i>) -> (ResolveResult<'_>, Event<'i>) {
964 use Event::*;
965
966 match event {
967 Empty(e) => (self.resolve_prefix(e.name().prefix(), true), Empty(e)),
968 Start(e) => (self.resolve_prefix(e.name().prefix(), true), Start(e)),
969 End(e) => (self.resolve_prefix(e.name().prefix(), true), End(e)),
970 e => (ResolveResult::Unbound, e),
971 }
972 }
973
974 /// Resolves given optional prefix (usually got from [`QName`]) into a corresponding namespace.
975 ///
976 /// # Parameters
977 /// - `prefix`: prefix to resolve, usually result of [`QName::prefix()`];
978 /// - `use_default`: whether to try to translate `None` prefix to the currently default namespace
979 /// (bound using `xmlns="default namespace"`) or return [`ResolveResult::Unbound`].
980 /// For attribute names this should be set to `false` and for element names to `true`.
981 pub fn resolve_prefix(&self, prefix: Option<Prefix>, use_default: bool) -> ResolveResult<'_> {
982 // Find the last defined binding that corresponds to the given prefix
983 let mut iter = self.bindings.iter().rev();
984 match (prefix, use_default) {
985 // Attribute name has no explicit prefix -> Unbound
986 (None, false) => ResolveResult::Unbound,
987 // Element name has no explicit prefix -> find nearest xmlns binding
988 (None, true) => match iter.find(|n| n.prefix_len == 0) {
989 Some(n) => n.namespace(&self.buffer),
990 None => ResolveResult::Unbound,
991 },
992 // Attribute or element name with explicit prefix
993 (Some(p), _) => match iter.find(|n| n.prefix(&self.buffer) == prefix) {
994 Some(n) if n.value_len != 0 => n.namespace(&self.buffer),
995 // Not found or binding reset (corresponds to `xmlns:p=""`)
996 _ => ResolveResult::Unknown(p.into_inner().to_string()),
997 },
998 }
999 }
1000
1001 /// Returns all the bindings currently in effect except the default `xml` and `xmlns` bindings.
1002 ///
1003 /// # Examples
1004 ///
1005 /// This example shows what results the returned iterator would return after
1006 /// reading each event of a simple XML.
1007 ///
1008 /// ```
1009 /// # use pretty_assertions::assert_eq;
1010 /// use quick_xml::name::{Namespace, PrefixDeclaration};
1011 /// use quick_xml::NsReader;
1012 ///
1013 /// let src = "<root>
1014 /// <a xmlns=\"a1\" xmlns:a=\"a2\">
1015 /// <b xmlns=\"b1\" xmlns:b=\"b2\">
1016 /// <c/>
1017 /// </b>
1018 /// <d/>
1019 /// </a>
1020 /// </root>";
1021 /// let mut reader = NsReader::from_str(src);
1022 /// reader.config_mut().trim_text(true);
1023 /// // No bindings at the beginning
1024 /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![]);
1025 ///
1026 /// reader.read_resolved_event()?; // <root>
1027 /// // No bindings declared on root
1028 /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![]);
1029 ///
1030 /// reader.read_resolved_event()?; // <a>
1031 /// // Two bindings declared on "a"
1032 /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![
1033 /// (PrefixDeclaration::Default, Namespace("a1")),
1034 /// (PrefixDeclaration::Named("a"), Namespace("a2"))
1035 /// ]);
1036 ///
1037 /// reader.read_resolved_event()?; // <b>
1038 /// // The default prefix got overridden and new "b" prefix
1039 /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![
1040 /// (PrefixDeclaration::Named("a"), Namespace("a2")),
1041 /// (PrefixDeclaration::Default, Namespace("b1")),
1042 /// (PrefixDeclaration::Named("b"), Namespace("b2"))
1043 /// ]);
1044 ///
1045 /// reader.read_resolved_event()?; // <c/>
1046 /// // Still the same
1047 /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![
1048 /// (PrefixDeclaration::Named("a"), Namespace("a2")),
1049 /// (PrefixDeclaration::Default, Namespace("b1")),
1050 /// (PrefixDeclaration::Named("b"), Namespace("b2"))
1051 /// ]);
1052 ///
1053 /// reader.read_resolved_event()?; // </b>
1054 /// // Still the same
1055 /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![
1056 /// (PrefixDeclaration::Named("a"), Namespace("a2")),
1057 /// (PrefixDeclaration::Default, Namespace("b1")),
1058 /// (PrefixDeclaration::Named("b"), Namespace("b2"))
1059 /// ]);
1060 ///
1061 /// reader.read_resolved_event()?; // <d/>
1062 /// // </b> got closed so back to the bindings declared on <a>
1063 /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![
1064 /// (PrefixDeclaration::Default, Namespace("a1")),
1065 /// (PrefixDeclaration::Named("a"), Namespace("a2"))
1066 /// ]);
1067 ///
1068 /// reader.read_resolved_event()?; // </a>
1069 /// // Still the same
1070 /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![
1071 /// (PrefixDeclaration::Default, Namespace("a1")),
1072 /// (PrefixDeclaration::Named("a"), Namespace("a2"))
1073 /// ]);
1074 ///
1075 /// reader.read_resolved_event()?; // </root>
1076 /// // <a> got closed
1077 /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![]);
1078 /// # quick_xml::Result::Ok(())
1079 /// ```
1080 #[inline]
1081 pub const fn bindings(&self) -> NamespaceBindingsIter<'_> {
1082 NamespaceBindingsIter {
1083 resolver: self,
1084 // We initialize the cursor to 2 to skip the two default namespaces xml: and xmlns:
1085 cursor: 2,
1086 }
1087 }
1088
1089 /// Returns all the bindings on the specified level, including the default
1090 /// `xml` and `xmlns` bindings.
1091 ///
1092 /// # Parameters
1093 /// - `level`: the nesting level of an XML tag. The document without tags has
1094 /// level 0, at which default bindings are declared. The root tag has level 1
1095 /// and all other tags has levels > 1. If specify level more than [current], the
1096 /// empty iterator is returned.
1097 ///
1098 /// # Examples
1099 ///
1100 /// This example shows what results the returned iterator would return on each
1101 /// level after reaning some events of a simple XML.
1102 ///
1103 /// ```
1104 /// # use pretty_assertions::assert_eq;
1105 /// use quick_xml::name::{Namespace, PrefixDeclaration};
1106 /// use quick_xml::NsReader;
1107 ///
1108 /// let src = "<root>
1109 /// <a xmlns=\"a1\" xmlns:a=\"a2\">
1110 /// <b xmlns=\"b1\" xmlns:b=\"b2\">
1111 /// <c/>
1112 /// </b>
1113 /// <d/>
1114 /// </a>
1115 /// </root>";
1116 /// let mut reader = NsReader::from_str(src);
1117 /// reader.config_mut().trim_text(true);
1118 /// reader.read_resolved_event()?; // <root>
1119 /// reader.read_resolved_event()?; // <a>
1120 /// reader.read_resolved_event()?; // <b>
1121 /// reader.read_resolved_event()?; // <c/>
1122 ///
1123 /// // Default bindings at the beginning
1124 /// assert_eq!(reader.resolver().bindings_of(0).collect::<Vec<_>>(), vec![
1125 /// (PrefixDeclaration::Named("xml"), Namespace("http://www.w3.org/XML/1998/namespace")),
1126 /// (PrefixDeclaration::Named("xmlns"), Namespace("http://www.w3.org/2000/xmlns/")),
1127 /// ]);
1128 ///
1129 /// // No bindings declared on root
1130 /// assert_eq!(reader.resolver().bindings_of(1).collect::<Vec<_>>(), vec![]);
1131 ///
1132 /// // Two bindings declared on "a"
1133 /// assert_eq!(reader.resolver().bindings_of(2).collect::<Vec<_>>(), vec![
1134 /// (PrefixDeclaration::Default, Namespace("a1")),
1135 /// (PrefixDeclaration::Named("a"), Namespace("a2")),
1136 /// ]);
1137 ///
1138 /// // Two bindings declared on "b"
1139 /// assert_eq!(reader.resolver().bindings_of(3).collect::<Vec<_>>(), vec![
1140 /// (PrefixDeclaration::Default, Namespace("b1")),
1141 /// (PrefixDeclaration::Named("b"), Namespace("b2")),
1142 /// ]);
1143 ///
1144 /// // No bindings declared on "c"
1145 /// assert_eq!(reader.resolver().bindings_of(4).collect::<Vec<_>>(), vec![]);
1146 ///
1147 /// // No bindings on non-existent level
1148 /// assert_eq!(reader.resolver().bindings_of(5).collect::<Vec<_>>(), vec![]);
1149 /// # quick_xml::Result::Ok(())
1150 /// ```
1151 ///
1152 /// [current]: Self::level
1153 pub const fn bindings_of(&self, level: u16) -> NamespaceBindingsOfLevelIter<'_> {
1154 NamespaceBindingsOfLevelIter {
1155 resolver: self,
1156 cursor: 0,
1157 level,
1158 }
1159 }
1160
1161 /// Returns the number of [`push`] calls that were not followed by [`pop`] calls.
1162 ///
1163 /// Due to use of `u16` for level number the number of nested tags in XML
1164 /// are limited by [`u16::MAX`], but that is enough for any real application.
1165 ///
1166 /// # Example
1167 ///
1168 /// ```
1169 /// # use pretty_assertions::assert_eq;
1170 /// # use quick_xml::events::BytesStart;
1171 /// # use quick_xml::name::{Namespace, NamespaceResolver, PrefixDeclaration, QName, ResolveResult};
1172 /// #
1173 /// let mut resolver = NamespaceResolver::default();
1174 ///
1175 /// assert_eq!(resolver.level(), 0);
1176 ///
1177 /// resolver.push(&BytesStart::new("tag"));
1178 /// assert_eq!(resolver.level(), 1);
1179 ///
1180 /// resolver.pop();
1181 /// assert_eq!(resolver.level(), 0);
1182 ///
1183 /// // pop from empty resolver does nothing
1184 /// resolver.pop();
1185 /// assert_eq!(resolver.level(), 0);
1186 /// ```
1187 ///
1188 /// [`push`]: Self::push
1189 /// [`pop`]: Self::pop
1190 pub const fn level(&self) -> u16 {
1191 self.nesting_level
1192 }
1193}
1194
1195////////////////////////////////////////////////////////////////////////////////////////////////////
1196
1197/// Iterator on the current declared namespace bindings. Returns pairs of the _(prefix, namespace)_.
1198///
1199/// See [`NamespaceResolver::bindings`] for documentation.
1200#[derive(Debug, Clone)]
1201pub struct NamespaceBindingsIter<'a> {
1202 resolver: &'a NamespaceResolver,
1203 cursor: usize,
1204}
1205
1206impl<'a> Iterator for NamespaceBindingsIter<'a> {
1207 type Item = (PrefixDeclaration<'a>, Namespace<'a>);
1208
1209 fn next(&mut self) -> Option<(PrefixDeclaration<'a>, Namespace<'a>)> {
1210 while let Some(binding) = self.resolver.bindings.get(self.cursor) {
1211 self.cursor += 1; // We increment for next read
1212
1213 // We check if the key has not been overridden by having a look
1214 // at the namespaces declared after in the array
1215 let prefix = binding.prefix(&self.resolver.buffer);
1216 if self.resolver.bindings[self.cursor..]
1217 .iter()
1218 .any(|ne| prefix == ne.prefix(&self.resolver.buffer))
1219 {
1220 continue; // Overridden
1221 }
1222 if let ResolveResult::Bound(namespace) = binding.namespace(&self.resolver.buffer) {
1223 let prefix = match prefix {
1224 Some(Prefix(prefix)) => PrefixDeclaration::Named(prefix),
1225 None => PrefixDeclaration::Default,
1226 };
1227 return Some((prefix, namespace));
1228 }
1229 }
1230 None // We have exhausted the array
1231 }
1232
1233 fn size_hint(&self) -> (usize, Option<usize>) {
1234 // Real count could be less if some namespaces was overridden
1235 (0, Some(self.resolver.bindings.len() - self.cursor))
1236 }
1237}
1238
1239impl<'a> FusedIterator for NamespaceBindingsIter<'a> {}
1240
1241/// Iterator on the declared namespace bindings on specified level. Returns pairs of the _(prefix, namespace)_.
1242///
1243/// See [`NamespaceResolver::bindings_of`] for documentation.
1244#[derive(Debug, Clone)]
1245pub struct NamespaceBindingsOfLevelIter<'a> {
1246 resolver: &'a NamespaceResolver,
1247 cursor: usize,
1248 level: u16,
1249}
1250
1251impl<'a> Iterator for NamespaceBindingsOfLevelIter<'a> {
1252 type Item = (PrefixDeclaration<'a>, Namespace<'a>);
1253
1254 fn next(&mut self) -> Option<(PrefixDeclaration<'a>, Namespace<'a>)> {
1255 while let Some(binding) = self.resolver.bindings.get(self.cursor) {
1256 self.cursor += 1; // We increment for next read
1257 if binding.level < self.level {
1258 continue;
1259 }
1260 if binding.level > self.level {
1261 break;
1262 }
1263
1264 if let ResolveResult::Bound(namespace) = binding.namespace(&self.resolver.buffer) {
1265 let prefix = match binding.prefix(&self.resolver.buffer) {
1266 Some(Prefix(prefix)) => PrefixDeclaration::Named(prefix),
1267 None => PrefixDeclaration::Default,
1268 };
1269 return Some((prefix, namespace));
1270 }
1271 }
1272 None // We have exhausted the array
1273 }
1274
1275 fn size_hint(&self) -> (usize, Option<usize>) {
1276 // Real count could be less
1277 (0, Some(self.resolver.bindings.len() - self.cursor))
1278 }
1279}
1280
1281impl<'a> FusedIterator for NamespaceBindingsOfLevelIter<'a> {}
1282
1283////////////////////////////////////////////////////////////////////////////////////////////////////
1284
1285#[cfg(test)]
1286mod namespaces {
1287 use super::*;
1288 use ResolveResult::*;
1289 use pretty_assertions::assert_eq;
1290
1291 /// Regression test for <https://github.com/tafia/quick-xml/issues/970>: a single element with
1292 /// many `xmlns:*` declarations must be rejected once the total binding count exceeds the limit.
1293 #[test]
1294 fn rejects_too_many_bindings_on_single_element() {
1295 let limit = DEFAULT_MAX_NAMESPACE_BINDINGS;
1296
1297 // One more than the limit triggers the error.
1298 let mut tag = String::from("e");
1299 for i in 0..=limit {
1300 tag.push_str(&format!(" xmlns:p{}=''", i));
1301 }
1302 let mut resolver = NamespaceResolver::default();
1303 assert_eq!(
1304 resolver.push(&BytesStart::from_content(&tag, 1)),
1305 Err(NamespaceError::TooManyBindings(limit)),
1306 );
1307
1308 // Exactly at the limit is accepted.
1309 let mut tag = String::from("e");
1310 for i in 0..limit {
1311 tag.push_str(&format!(" xmlns:p{}=''", i));
1312 }
1313 let mut resolver = NamespaceResolver::default();
1314 assert_eq!(resolver.push(&BytesStart::from_content(&tag, 1)), Ok(()));
1315
1316 // The limit is configurable, and `usize::MAX` disables it.
1317 let mut resolver = NamespaceResolver::default();
1318 resolver.set_max_namespace_bindings(2);
1319 assert_eq!(
1320 resolver.push(&BytesStart::from_content(
1321 "e xmlns:a='' xmlns:b='' xmlns:c=''",
1322 1,
1323 )),
1324 Err(NamespaceError::TooManyBindings(2)),
1325 );
1326 let mut resolver = NamespaceResolver::default();
1327 resolver.set_max_namespace_bindings(usize::MAX);
1328 assert_eq!(
1329 resolver.push(&BytesStart::from_content(
1330 "e xmlns:a='' xmlns:b='' xmlns:c=''",
1331 1,
1332 )),
1333 Ok(()),
1334 );
1335 }
1336
1337 /// Regression test for <https://github.com/tafia/quick-xml/issues/980>:
1338 /// deeply nested documents where each level declares one `xmlns:*`
1339 /// binding must be rejected once the total binding count exceeds the
1340 /// limit, preventing O(depth²) CPU exhaustion in `resolve_prefix`.
1341 #[test]
1342 fn rejects_too_many_bindings_across_elements() {
1343 let limit = 10;
1344 let mut resolver = NamespaceResolver::default();
1345 resolver.set_max_namespace_bindings(limit);
1346
1347 // Push elements, each declaring one new namespace binding.
1348 for i in 0..limit {
1349 let tag = format!("e xmlns:p{}='ns{}'", i, i);
1350 assert_eq!(
1351 resolver.push(&BytesStart::from_content(&tag, 1)),
1352 Ok(()),
1353 "push {} should succeed",
1354 i,
1355 );
1356 }
1357
1358 // The next binding (on a new element) exceeds the limit.
1359 assert_eq!(
1360 resolver.push(&BytesStart::from_content("e xmlns:extra='ns'", 1)),
1361 Err(NamespaceError::TooManyBindings(limit)),
1362 );
1363
1364 // An element without namespace declarations is still fine.
1365 assert_eq!(resolver.push(&BytesStart::from_content("e", 1)), Ok(()),);
1366 }
1367
1368 /// Popping scopes makes room for new bindings under the limit.
1369 #[test]
1370 fn popping_frees_room_for_bindings() {
1371 let limit = 10;
1372 let mut resolver = NamespaceResolver::default();
1373 resolver.set_max_namespace_bindings(limit);
1374
1375 // Fill to the limit.
1376 for i in 0..limit {
1377 let tag = format!("e xmlns:p{}='ns{}'", i, i);
1378 resolver.push(&BytesStart::from_content(&tag, 1)).unwrap();
1379 }
1380
1381 // Pop the last element's scope — frees one binding slot.
1382 resolver.pop();
1383
1384 // Now a new binding fits.
1385 assert_eq!(
1386 resolver.push(&BytesStart::from_content("e xmlns:new='ns'", 1)),
1387 Ok(()),
1388 );
1389 }
1390
1391 /// Regression test for <https://github.com/tafia/quick-xml/issues/977>:
1392 /// `push()` previously incremented a `u16` depth counter with an unguarded
1393 /// `+= 1`, so a document nested past `u16::MAX` panicked under
1394 /// `overflow-checks` or silently wrapped the counter and corrupted namespace
1395 /// scoping in release. It now returns `TooDeeplyNested` at the boundary.
1396 #[test]
1397 fn push_rejects_pathological_nesting_depth() {
1398 let mut resolver = NamespaceResolver::default();
1399 let tag = BytesStart::from_content("a", 1);
1400 // `u16::MAX` successful pushes, then the next is rejected cleanly.
1401 for _ in 0..u16::MAX {
1402 assert_eq!(resolver.push(&tag), Ok(()));
1403 }
1404 assert_eq!(
1405 resolver.push(&tag),
1406 Err(NamespaceError::TooDeeplyNested(u16::MAX as usize)),
1407 );
1408 }
1409
1410 /// Unprefixed attribute names (resolved with `false` flag) never have a namespace
1411 /// according to <https://www.w3.org/TR/xml-names11/#defaulting>:
1412 ///
1413 /// > A default namespace declaration applies to all unprefixed element names
1414 /// > within its scope. Default namespace declarations do not apply directly
1415 /// > to attribute names; the interpretation of unprefixed attributes is
1416 /// > determined by the element on which they appear.
1417 mod unprefixed {
1418 use super::*;
1419 use pretty_assertions::assert_eq;
1420
1421 /// Basic tests that checks that basic resolver functionality is working
1422 #[test]
1423 fn basic() {
1424 let name = QName("simple");
1425 let ns = Namespace("default");
1426
1427 let mut resolver = NamespaceResolver::default();
1428 let s = resolver.buffer.len();
1429
1430 resolver
1431 .push(&BytesStart::from_content(" xmlns='default'", 0))
1432 .unwrap();
1433 assert_eq!(&resolver.buffer[s..], "default");
1434
1435 // Check that tags without namespaces does not change result
1436 resolver.push(&BytesStart::from_content("", 0)).unwrap();
1437 assert_eq!(&resolver.buffer[s..], "default");
1438 resolver.pop();
1439
1440 assert_eq!(&resolver.buffer[s..], "default");
1441 assert_eq!(
1442 resolver.resolve(name, true),
1443 (Bound(ns), LocalName("simple"))
1444 );
1445 assert_eq!(
1446 resolver.resolve(name, false),
1447 (Unbound, LocalName("simple"))
1448 );
1449 }
1450
1451 /// Test adding a second level of namespaces, which replaces the previous binding
1452 #[test]
1453 fn override_namespace() {
1454 let name = QName("simple");
1455 let old_ns = Namespace("old");
1456 let new_ns = Namespace("new");
1457
1458 let mut resolver = NamespaceResolver::default();
1459 let s = resolver.buffer.len();
1460
1461 resolver
1462 .push(&BytesStart::from_content(" xmlns='old'", 0))
1463 .unwrap();
1464 resolver
1465 .push(&BytesStart::from_content(" xmlns='new'", 0))
1466 .unwrap();
1467
1468 assert_eq!(&resolver.buffer[s..], "oldnew");
1469 assert_eq!(
1470 resolver.resolve(name, true),
1471 (Bound(new_ns), LocalName("simple"))
1472 );
1473 assert_eq!(
1474 resolver.resolve(name, false),
1475 (Unbound, LocalName("simple"))
1476 );
1477
1478 resolver.pop();
1479 assert_eq!(&resolver.buffer[s..], "old");
1480 assert_eq!(
1481 resolver.resolve(name, true),
1482 (Bound(old_ns), LocalName("simple"))
1483 );
1484 assert_eq!(
1485 resolver.resolve(name, false),
1486 (Unbound, LocalName("simple"))
1487 );
1488 }
1489
1490 /// Test adding a second level of namespaces, which reset the previous binding
1491 /// to not bound state by specifying an empty namespace name.
1492 ///
1493 /// See <https://www.w3.org/TR/xml-names11/#scoping>
1494 #[test]
1495 fn reset() {
1496 let name = QName("simple");
1497 let old_ns = Namespace("old");
1498
1499 let mut resolver = NamespaceResolver::default();
1500 let s = resolver.buffer.len();
1501
1502 resolver
1503 .push(&BytesStart::from_content(" xmlns='old'", 0))
1504 .unwrap();
1505 resolver
1506 .push(&BytesStart::from_content(" xmlns=''", 0))
1507 .unwrap();
1508
1509 assert_eq!(&resolver.buffer[s..], "old");
1510 assert_eq!(resolver.resolve(name, true), (Unbound, LocalName("simple")));
1511 assert_eq!(
1512 resolver.resolve(name, false),
1513 (Unbound, LocalName("simple"))
1514 );
1515
1516 resolver.pop();
1517 assert_eq!(&resolver.buffer[s..], "old");
1518 assert_eq!(
1519 resolver.resolve(name, true),
1520 (Bound(old_ns), LocalName("simple"))
1521 );
1522 assert_eq!(
1523 resolver.resolve(name, false),
1524 (Unbound, LocalName("simple"))
1525 );
1526 }
1527 }
1528
1529 mod declared_prefix {
1530 use super::*;
1531 use pretty_assertions::assert_eq;
1532
1533 /// Basic tests that checks that basic resolver functionality is working
1534 #[test]
1535 fn basic() {
1536 let name = QName("p:with-declared-prefix");
1537 let ns = Namespace("default");
1538
1539 let mut resolver = NamespaceResolver::default();
1540 let s = resolver.buffer.len();
1541
1542 resolver
1543 .push(&BytesStart::from_content(" xmlns:p='default'", 0))
1544 .unwrap();
1545 assert_eq!(&resolver.buffer[s..], "pdefault");
1546
1547 // Check that tags without namespaces does not change result
1548 resolver.push(&BytesStart::from_content("", 0)).unwrap();
1549 assert_eq!(&resolver.buffer[s..], "pdefault");
1550 resolver.pop();
1551
1552 assert_eq!(&resolver.buffer[s..], "pdefault");
1553 assert_eq!(
1554 resolver.resolve(name, true),
1555 (Bound(ns), LocalName("with-declared-prefix"))
1556 );
1557 assert_eq!(
1558 resolver.resolve(name, false),
1559 (Bound(ns), LocalName("with-declared-prefix"))
1560 );
1561 }
1562
1563 /// Test adding a second level of namespaces, which replaces the previous binding
1564 #[test]
1565 fn override_namespace() {
1566 let name = QName("p:with-declared-prefix");
1567 let old_ns = Namespace("old");
1568 let new_ns = Namespace("new");
1569
1570 let mut resolver = NamespaceResolver::default();
1571 let s = resolver.buffer.len();
1572
1573 resolver
1574 .push(&BytesStart::from_content(" xmlns:p='old'", 0))
1575 .unwrap();
1576 resolver
1577 .push(&BytesStart::from_content(" xmlns:p='new'", 0))
1578 .unwrap();
1579
1580 assert_eq!(&resolver.buffer[s..], "poldpnew");
1581 assert_eq!(
1582 resolver.resolve(name, true),
1583 (Bound(new_ns), LocalName("with-declared-prefix"))
1584 );
1585 assert_eq!(
1586 resolver.resolve(name, false),
1587 (Bound(new_ns), LocalName("with-declared-prefix"))
1588 );
1589
1590 resolver.pop();
1591 assert_eq!(&resolver.buffer[s..], "pold");
1592 assert_eq!(
1593 resolver.resolve(name, true),
1594 (Bound(old_ns), LocalName("with-declared-prefix"))
1595 );
1596 assert_eq!(
1597 resolver.resolve(name, false),
1598 (Bound(old_ns), LocalName("with-declared-prefix"))
1599 );
1600 }
1601
1602 /// Test adding a second level of namespaces, which reset the previous binding
1603 /// to not bound state by specifying an empty namespace name.
1604 ///
1605 /// See <https://www.w3.org/TR/xml-names11/#scoping>
1606 #[test]
1607 fn reset() {
1608 let name = QName("p:with-declared-prefix");
1609 let old_ns = Namespace("old");
1610
1611 let mut resolver = NamespaceResolver::default();
1612 let s = resolver.buffer.len();
1613
1614 resolver
1615 .push(&BytesStart::from_content(" xmlns:p='old'", 0))
1616 .unwrap();
1617 resolver
1618 .push(&BytesStart::from_content(" xmlns:p=''", 0))
1619 .unwrap();
1620
1621 assert_eq!(&resolver.buffer[s..], "poldp");
1622 assert_eq!(
1623 resolver.resolve(name, true),
1624 (Unknown("p".to_string()), LocalName("with-declared-prefix"))
1625 );
1626 assert_eq!(
1627 resolver.resolve(name, false),
1628 (Unknown("p".to_string()), LocalName("with-declared-prefix"))
1629 );
1630
1631 resolver.pop();
1632 assert_eq!(&resolver.buffer[s..], "pold");
1633 assert_eq!(
1634 resolver.resolve(name, true),
1635 (Bound(old_ns), LocalName("with-declared-prefix"))
1636 );
1637 assert_eq!(
1638 resolver.resolve(name, false),
1639 (Bound(old_ns), LocalName("with-declared-prefix"))
1640 );
1641 }
1642 }
1643
1644 /// Tests for `xml` and `xmlns` built-in prefixes.
1645 ///
1646 /// See <https://www.w3.org/TR/xml-names11/#xmlReserved>
1647 mod builtin_prefixes {
1648 use super::*;
1649
1650 mod xml {
1651 use super::*;
1652 use pretty_assertions::assert_eq;
1653
1654 /// `xml` prefix are always defined, it is not required to define it explicitly.
1655 #[test]
1656 fn undeclared() {
1657 let name = QName("xml:random");
1658 let namespace = RESERVED_NAMESPACE_XML.1;
1659
1660 let resolver = NamespaceResolver::default();
1661
1662 assert_eq!(
1663 resolver.resolve(name, true),
1664 (Bound(namespace), LocalName("random"))
1665 );
1666
1667 assert_eq!(
1668 resolver.resolve(name, false),
1669 (Bound(namespace), LocalName("random"))
1670 );
1671 }
1672
1673 /// `xml` prefix can be declared but it must be bound to the value
1674 /// `http://www.w3.org/XML/1998/namespace`
1675 #[test]
1676 fn rebound_to_correct_ns() {
1677 let mut resolver = NamespaceResolver::default();
1678 let s = resolver.buffer.len();
1679 resolver.push(
1680 &BytesStart::from_content(
1681 " xmlns:xml='http://www.w3.org/XML/1998/namespace'",
1682 0,
1683 ),
1684 ).expect("`xml` prefix should be possible to bound to `http://www.w3.org/XML/1998/namespace`");
1685 assert_eq!(&resolver.buffer[s..], "");
1686 }
1687
1688 /// `xml` prefix cannot be re-declared to another namespace
1689 #[test]
1690 fn rebound_to_incorrect_ns() {
1691 let mut resolver = NamespaceResolver::default();
1692 let s = resolver.buffer.len();
1693 assert_eq!(
1694 resolver.push(&BytesStart::from_content(
1695 " xmlns:xml='not_correct_namespace'",
1696 0,
1697 )),
1698 Err(NamespaceError::InvalidXmlPrefixBind(
1699 "not_correct_namespace".to_string()
1700 )),
1701 );
1702 assert_eq!(&resolver.buffer[s..], "");
1703 }
1704
1705 /// `xml` prefix cannot be unbound
1706 #[test]
1707 fn unbound() {
1708 let mut resolver = NamespaceResolver::default();
1709 let s = resolver.buffer.len();
1710 assert_eq!(
1711 resolver.push(&BytesStart::from_content(" xmlns:xml=''", 0)),
1712 Err(NamespaceError::InvalidXmlPrefixBind("".to_string())),
1713 );
1714 assert_eq!(&resolver.buffer[s..], "");
1715 }
1716
1717 /// Other prefix cannot be bound to `xml` namespace
1718 #[test]
1719 fn other_prefix_bound_to_xml_namespace() {
1720 let mut resolver = NamespaceResolver::default();
1721 let s = resolver.buffer.len();
1722 assert_eq!(
1723 resolver.push(&BytesStart::from_content(
1724 " xmlns:not_xml='http://www.w3.org/XML/1998/namespace'",
1725 0,
1726 )),
1727 Err(NamespaceError::InvalidPrefixForXml("not_xml".to_string())),
1728 );
1729 assert_eq!(&resolver.buffer[s..], "");
1730 }
1731 }
1732
1733 mod xmlns {
1734 use super::*;
1735 use pretty_assertions::assert_eq;
1736
1737 /// `xmlns` prefix are always defined, it is forbidden to define it explicitly
1738 #[test]
1739 fn undeclared() {
1740 let name = QName("xmlns:random");
1741 let namespace = RESERVED_NAMESPACE_XMLNS.1;
1742
1743 let resolver = NamespaceResolver::default();
1744
1745 assert_eq!(
1746 resolver.resolve(name, true),
1747 (Bound(namespace), LocalName("random"))
1748 );
1749
1750 assert_eq!(
1751 resolver.resolve(name, false),
1752 (Bound(namespace), LocalName("random"))
1753 );
1754 }
1755
1756 /// `xmlns` prefix cannot be re-declared event to its own namespace
1757 #[test]
1758 fn rebound_to_correct_ns() {
1759 let mut resolver = NamespaceResolver::default();
1760 let s = resolver.buffer.len();
1761 assert_eq!(
1762 resolver.push(&BytesStart::from_content(
1763 " xmlns:xmlns='http://www.w3.org/2000/xmlns/'",
1764 0,
1765 )),
1766 Err(NamespaceError::InvalidXmlnsPrefixBind(
1767 "http://www.w3.org/2000/xmlns/".to_string()
1768 )),
1769 );
1770 assert_eq!(&resolver.buffer[s..], "");
1771 }
1772
1773 /// `xmlns` prefix cannot be re-declared
1774 #[test]
1775 fn rebound_to_incorrect_ns() {
1776 let mut resolver = NamespaceResolver::default();
1777 let s = resolver.buffer.len();
1778 assert_eq!(
1779 resolver.push(&BytesStart::from_content(
1780 " xmlns:xmlns='not_correct_namespace'",
1781 0,
1782 )),
1783 Err(NamespaceError::InvalidXmlnsPrefixBind(
1784 "not_correct_namespace".to_string()
1785 )),
1786 );
1787 assert_eq!(&resolver.buffer[s..], "");
1788 }
1789
1790 /// `xmlns` prefix cannot be unbound
1791 #[test]
1792 fn unbound() {
1793 let mut resolver = NamespaceResolver::default();
1794 let s = resolver.buffer.len();
1795 assert_eq!(
1796 resolver.push(&BytesStart::from_content(" xmlns:xmlns=''", 0)),
1797 Err(NamespaceError::InvalidXmlnsPrefixBind("".to_string())),
1798 );
1799 assert_eq!(&resolver.buffer[s..], "");
1800 }
1801
1802 /// Other prefix cannot be bound to `xmlns` namespace
1803 #[test]
1804 fn other_prefix_bound_to_xmlns_namespace() {
1805 let mut resolver = NamespaceResolver::default();
1806 let s = resolver.buffer.len();
1807 assert_eq!(
1808 resolver.push(&BytesStart::from_content(
1809 " xmlns:not_xmlns='http://www.w3.org/2000/xmlns/'",
1810 0,
1811 )),
1812 Err(NamespaceError::InvalidPrefixForXmlns(
1813 "not_xmlns".to_string()
1814 )),
1815 );
1816 assert_eq!(&resolver.buffer[s..], "");
1817 }
1818 }
1819 }
1820
1821 #[test]
1822 fn undeclared_prefix() {
1823 let name = QName("unknown:prefix");
1824
1825 let resolver = NamespaceResolver::default();
1826
1827 assert_eq!(
1828 resolver.buffer,
1829 "xmlhttp://www.w3.org/XML/1998/namespacexmlnshttp://www.w3.org/2000/xmlns/"
1830 );
1831 assert_eq!(
1832 resolver.resolve(name, true),
1833 (Unknown("unknown".to_string()), LocalName("prefix"))
1834 );
1835 assert_eq!(
1836 resolver.resolve(name, false),
1837 (Unknown("unknown".to_string()), LocalName("prefix"))
1838 );
1839 }
1840
1841 /// Checks how the QName is decomposed to a prefix and a local name
1842 #[test]
1843 fn prefix_and_local_name() {
1844 let name = QName("foo:bus");
1845 assert_eq!(name.prefix(), Some(Prefix("foo")));
1846 assert_eq!(name.local_name(), LocalName("bus"));
1847 assert_eq!(name.decompose(), (LocalName("bus"), Some(Prefix("foo"))));
1848
1849 let name = QName("foo:");
1850 assert_eq!(name.prefix(), Some(Prefix("foo")));
1851 assert_eq!(name.local_name(), LocalName(""));
1852 assert_eq!(name.decompose(), (LocalName(""), Some(Prefix("foo"))));
1853
1854 let name = QName(":foo");
1855 assert_eq!(name.prefix(), Some(Prefix("")));
1856 assert_eq!(name.local_name(), LocalName("foo"));
1857 assert_eq!(name.decompose(), (LocalName("foo"), Some(Prefix(""))));
1858
1859 let name = QName("foo:bus:baz");
1860 assert_eq!(name.prefix(), Some(Prefix("foo")));
1861 assert_eq!(name.local_name(), LocalName("bus:baz"));
1862 assert_eq!(
1863 name.decompose(),
1864 (LocalName("bus:baz"), Some(Prefix("foo")))
1865 );
1866 }
1867}