@@ -365,7 +365,7 @@ impl<'a> AsRef<[u8]> for Namespace<'a> {
365365
366366////////////////////////////////////////////////////////////////////////////////////////////////////
367367
368- /// Result of [prefix] resolution which creates by [`NsReader::resolve_attribute`],
368+ /// Result of [prefix] resolution which creates by [`NamespaceResolver::resolve`], [` NsReader::resolve_attribute`],
369369/// [`NsReader::resolve_element`], [`NsReader::read_resolved_event`] and
370370/// [`NsReader::read_resolved_event_into`] methods.
371371///
@@ -478,11 +478,12 @@ impl NamespaceBinding {
478478 }
479479}
480480
481- /// A namespace management buffer.
481+ /// A storage for currently defined namespace bindings, which is used to resolve
482+ /// prefixes into namespaces.
482483///
483484/// Holds all internal logic to push/pop namespaces with their levels.
484485#[ derive( Debug , Clone ) ]
485- pub ( crate ) struct NamespaceResolver {
486+ pub struct NamespaceResolver {
486487 /// Buffer that contains names of namespace prefixes (the part between `xmlns:`
487488 /// and an `=`) and namespace values.
488489 buffer : Vec < u8 > ,
@@ -510,7 +511,7 @@ const RESERVED_NAMESPACE_XML: (Prefix, Namespace) = (
510511/// The prefix `xmlns` is used only to declare namespace bindings and is by definition bound
511512/// to the namespace name `http://www.w3.org/2000/xmlns/`. It must not be declared or
512513/// undeclared. Other prefixes must not be bound to this namespace name, and it must not be
513- /// declared as the default namespace. Element names must not have the prefix `xmlns`.
514+ /// declared as the default namespace. Element names must not have the prefix `xmlns`.
514515///
515516/// [reserved namespaces]: https://www.w3.org/TR/xml-names11/#xmlReserved
516517const RESERVED_NAMESPACE_XMLNS : ( Prefix , Namespace ) = (
@@ -547,7 +548,7 @@ impl NamespaceResolver {
547548 /// Begins a new scope and add to it all [namespace bindings] that found in
548549 /// the specified start element.
549550 ///
550- /// [namespace binding ]: https://www.w3.org/TR/xml-names11/#dt-NSDecl
551+ /// [namespace bindings ]: https://www.w3.org/TR/xml-names11/#dt-NSDecl
551552 pub fn push ( & mut self , start : & BytesStart ) -> Result < ( ) , NamespaceError > {
552553 self . nesting_level += 1 ;
553554 let level = self . nesting_level ;
@@ -607,10 +608,10 @@ impl NamespaceResolver {
607608 Ok ( ( ) )
608609 }
609610
610- /// Ends a top-most scope by popping all [namespace binding ], that was added by
611+ /// Ends a top-most scope by popping all [namespace bindings ], that was added by
611612 /// last call to [`Self::push()`].
612613 ///
613- /// [namespace binding ]: https://www.w3.org/TR/xml-names11/#dt-NSDecl
614+ /// [namespace bindings ]: https://www.w3.org/TR/xml-names11/#dt-NSDecl
614615 pub fn pop ( & mut self ) {
615616 self . nesting_level -= 1 ;
616617 let current_level = self . nesting_level ;
@@ -632,18 +633,38 @@ impl NamespaceResolver {
632633 }
633634
634635 /// Resolves a potentially qualified **element name** or **attribute name**
635- /// into (namespace name, local name).
636+ /// into _ (namespace name, local name)_ .
636637 ///
637- /// *Qualified* names have the form `prefix:local-name` where the `prefix` is
638- /// defined on any containing XML element via `xmlns:prefix="the:namespace:uri"`.
639- /// The namespace prefix can be defined on the same element as the element or
640- /// attribute in question.
638+ /// _Qualified_ names have the form `local-name` or `prefix:local-name` where the `prefix`
639+ /// is defined on any containing XML element via `xmlns:prefix="the:namespace:uri"`.
640+ /// The namespace prefix can be defined on the same element as the name in question.
641641 ///
642- /// *Unqualified* attribute names do *not* inherit the current *default namespace*.
642+ /// The method returns following results depending on the `name` shape, `attribute` flag
643+ /// and the presence of the default namespace on element or any of its parents:
644+ ///
645+ /// |use_default|`xmlns="..."`|QName |ResolveResult |LocalName
646+ /// |-----------|-------------|-------------------|-----------------------|------------
647+ /// |`false` |_(any)_ |`local-name` |[`Unbound`] |`local-name`
648+ /// |`false` |_(any)_ |`prefix:local-name`|[`Bound`] / [`Unknown`]|`local-name`
649+ /// |`true` |Not defined |`local-name` |[`Unbound`] |`local-name`
650+ /// |`true` |Defined |`local-name` |[`Bound`] (to `xmlns`) |`local-name`
651+ /// |`true` |_(any)_ |`prefix:local-name`|[`Bound`] / [`Unknown`]|`local-name`
652+ ///
653+ /// # Parameters
654+ /// - `name`: probably qualified name to resolve;
655+ /// - `use_default`: whether to try to translate `None` prefix to the currently default namespace
656+ /// (bound using `xmlns="default namespace"`) or return [`ResolveResult::Unbound`].
657+ /// For attribute names this should be set to `false` and for element names to `true`.
643658 ///
644659 /// # Lifetimes
645660 ///
646- /// - `'n`: lifetime of an attribute or an element name
661+ /// - `'n`: lifetime of a name. Returned local name will be bound to the same
662+ /// lifetime as the name in question.
663+ /// - returned namespace name will be bound to the resolver itself
664+ ///
665+ /// [`Bound`]: ResolveResult::Bound
666+ /// [`Unbound`]: ResolveResult::Unbound
667+ /// [`Unknown`]: ResolveResult::Unknown
647668 #[ inline]
648669 pub fn resolve < ' n > (
649670 & self ,
@@ -669,7 +690,14 @@ impl NamespaceResolver {
669690 self . resolve_prefix ( element_name. prefix ( ) , true )
670691 }
671692
672- fn resolve_prefix ( & self , prefix : Option < Prefix > , use_default : bool ) -> ResolveResult < ' _ > {
693+ /// Resolves given optional prefix (usually got from [`QName`]) into a corresponding namespace.
694+ ///
695+ /// # Parameters
696+ /// - `prefix`: prefix to resolve, usually result of [`QName::prefix()`];
697+ /// - `use_default`: whether to try to translate `None` prefix to the currently default namespace
698+ /// (bound using `xmlns="default namespace"`) or return [`ResolveResult::Unbound`].
699+ /// For attribute names this should be set to `false` and for element names to `true`.
700+ pub fn resolve_prefix ( & self , prefix : Option < Prefix > , use_default : bool ) -> ResolveResult < ' _ > {
673701 // Find the last defined binding that corresponds to the given prefix
674702 let mut iter = self . bindings . iter ( ) . rev ( ) ;
675703 match ( prefix, use_default) {
@@ -689,6 +717,85 @@ impl NamespaceResolver {
689717 }
690718 }
691719
720+ /// Returns all the bindings currently in effect except the default `xml` and `xmlns` bindings.
721+ ///
722+ /// # Examples
723+ ///
724+ /// This example shows what results the returned iterator would return after
725+ /// reading each event of a simple XML.
726+ ///
727+ /// ```
728+ /// # use pretty_assertions::assert_eq;
729+ /// use quick_xml::name::{Namespace, PrefixDeclaration};
730+ /// use quick_xml::NsReader;
731+ ///
732+ /// let src = "<root>
733+ /// <a xmlns=\"a1\" xmlns:a=\"a2\">
734+ /// <b xmlns=\"b1\" xmlns:b=\"b2\">
735+ /// <c/>
736+ /// </b>
737+ /// <d/>
738+ /// </a>
739+ /// </root>";
740+ /// let mut reader = NsReader::from_str(src);
741+ /// reader.config_mut().trim_text(true);
742+ /// // No bindings at the beginning
743+ /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![]);
744+ ///
745+ /// reader.read_resolved_event()?; // <root>
746+ /// // No bindings declared on root
747+ /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![]);
748+ ///
749+ /// reader.read_resolved_event()?; // <a>
750+ /// // Two bindings declared on "a"
751+ /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![
752+ /// (PrefixDeclaration::Default, Namespace(b"a1")),
753+ /// (PrefixDeclaration::Named(b"a"), Namespace(b"a2"))
754+ /// ]);
755+ ///
756+ /// reader.read_resolved_event()?; // <b>
757+ /// // The default prefix got overridden and new "b" prefix
758+ /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![
759+ /// (PrefixDeclaration::Named(b"a"), Namespace(b"a2")),
760+ /// (PrefixDeclaration::Default, Namespace(b"b1")),
761+ /// (PrefixDeclaration::Named(b"b"), Namespace(b"b2"))
762+ /// ]);
763+ ///
764+ /// reader.read_resolved_event()?; // <c/>
765+ /// // Still the same
766+ /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![
767+ /// (PrefixDeclaration::Named(b"a"), Namespace(b"a2")),
768+ /// (PrefixDeclaration::Default, Namespace(b"b1")),
769+ /// (PrefixDeclaration::Named(b"b"), Namespace(b"b2"))
770+ /// ]);
771+ ///
772+ /// reader.read_resolved_event()?; // </b>
773+ /// // Still the same
774+ /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![
775+ /// (PrefixDeclaration::Named(b"a"), Namespace(b"a2")),
776+ /// (PrefixDeclaration::Default, Namespace(b"b1")),
777+ /// (PrefixDeclaration::Named(b"b"), Namespace(b"b2"))
778+ /// ]);
779+ ///
780+ /// reader.read_resolved_event()?; // <d/>
781+ /// // </b> got closed so back to the bindings declared on <a>
782+ /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![
783+ /// (PrefixDeclaration::Default, Namespace(b"a1")),
784+ /// (PrefixDeclaration::Named(b"a"), Namespace(b"a2"))
785+ /// ]);
786+ ///
787+ /// reader.read_resolved_event()?; // </a>
788+ /// // Still the same
789+ /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![
790+ /// (PrefixDeclaration::Default, Namespace(b"a1")),
791+ /// (PrefixDeclaration::Named(b"a"), Namespace(b"a2"))
792+ /// ]);
793+ ///
794+ /// reader.read_resolved_event()?; // </root>
795+ /// // <a> got closed
796+ /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![]);
797+ /// # quick_xml::Result::Ok(())
798+ /// ```
692799 #[ inline]
693800 pub const fn bindings ( & self ) -> NamespaceBindingsIter < ' _ > {
694801 NamespaceBindingsIter {
@@ -703,7 +810,7 @@ impl NamespaceResolver {
703810
704811/// Iterator on the current declared namespace bindings. Returns pairs of the _(prefix, namespace)_.
705812///
706- /// See [`NsReader::prefixes`](crate::NsReader::prefixes) for documentation.
813+ /// See [`NamespaceResolver::bindings`] for documentation.
707814#[ derive( Debug , Clone ) ]
708815pub struct NamespaceBindingsIter < ' a > {
709816 resolver : & ' a NamespaceResolver ,
0 commit comments