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