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