@@ -448,7 +448,7 @@ struct NamespaceBinding {
448448 /// Level of nesting at which this namespace was declared. The declaring element is included,
449449 /// i.e., a declaration on the document root has `level = 1`.
450450 /// This is used to pop the namespace when the element gets closed.
451- level : i32 ,
451+ level : u16 ,
452452}
453453
454454impl NamespaceBinding {
@@ -491,7 +491,7 @@ pub struct NamespaceResolver {
491491 bindings : Vec < NamespaceBinding > ,
492492 /// The number of open tags at the moment. We need to keep track of this to know which namespace
493493 /// declarations to remove when we encounter an `End` event.
494- nesting_level : i32 ,
494+ nesting_level : u16 ,
495495}
496496
497497/// That constant define the one of [reserved namespaces] for the xml standard.
@@ -613,7 +613,7 @@ impl NamespaceResolver {
613613 ///
614614 /// [namespace bindings]: https://www.w3.org/TR/xml-names11/#dt-NSDecl
615615 pub fn pop ( & mut self ) {
616- self . nesting_level -= 1 ;
616+ self . nesting_level = self . nesting_level . saturating_sub ( 1 ) ;
617617 let current_level = self . nesting_level ;
618618 // from the back (most deeply nested scope), look for the first scope that is still valid
619619 match self . bindings . iter ( ) . rposition ( |n| n. level <= current_level) {
@@ -866,6 +866,111 @@ impl NamespaceResolver {
866866 cursor : 2 ,
867867 }
868868 }
869+
870+ /// Returns all the bindings on the specified level, including the default
871+ /// `xml` and `xmlns` bindings.
872+ ///
873+ /// # Parameters
874+ /// - `level`: the nesting level of an XML tag. The document without tags has
875+ /// level 0, at which default bindings are declared. The root tag has level 1
876+ /// and all other tags has levels > 1. If specify level more than [current], the
877+ /// empty iterator is returned.
878+ ///
879+ /// # Examples
880+ ///
881+ /// This example shows what results the returned iterator would return on each
882+ /// level after reaning some events of a simple XML.
883+ ///
884+ /// ```
885+ /// # use pretty_assertions::assert_eq;
886+ /// use quick_xml::name::{Namespace, PrefixDeclaration};
887+ /// use quick_xml::NsReader;
888+ ///
889+ /// let src = "<root>
890+ /// <a xmlns=\"a1\" xmlns:a=\"a2\">
891+ /// <b xmlns=\"b1\" xmlns:b=\"b2\">
892+ /// <c/>
893+ /// </b>
894+ /// <d/>
895+ /// </a>
896+ /// </root>";
897+ /// let mut reader = NsReader::from_str(src);
898+ /// reader.config_mut().trim_text(true);
899+ /// reader.read_resolved_event()?; // <root>
900+ /// reader.read_resolved_event()?; // <a>
901+ /// reader.read_resolved_event()?; // <b>
902+ /// reader.read_resolved_event()?; // <c/>
903+ ///
904+ /// // Default bindings at the beginning
905+ /// assert_eq!(reader.resolver().bindings_of(0).collect::<Vec<_>>(), vec![
906+ /// (PrefixDeclaration::Named(b"xml"), Namespace(b"http://www.w3.org/XML/1998/namespace")),
907+ /// (PrefixDeclaration::Named(b"xmlns"), Namespace(b"http://www.w3.org/2000/xmlns/")),
908+ /// ]);
909+ ///
910+ /// // No bindings declared on root
911+ /// assert_eq!(reader.resolver().bindings_of(1).collect::<Vec<_>>(), vec![]);
912+ ///
913+ /// // Two bindings declared on "a"
914+ /// assert_eq!(reader.resolver().bindings_of(2).collect::<Vec<_>>(), vec![
915+ /// (PrefixDeclaration::Default, Namespace(b"a1")),
916+ /// (PrefixDeclaration::Named(b"a"), Namespace(b"a2")),
917+ /// ]);
918+ ///
919+ /// // Two bindings declared on "b"
920+ /// assert_eq!(reader.resolver().bindings_of(3).collect::<Vec<_>>(), vec![
921+ /// (PrefixDeclaration::Default, Namespace(b"b1")),
922+ /// (PrefixDeclaration::Named(b"b"), Namespace(b"b2")),
923+ /// ]);
924+ ///
925+ /// // No bindings declared on "c"
926+ /// assert_eq!(reader.resolver().bindings_of(4).collect::<Vec<_>>(), vec![]);
927+ ///
928+ /// // No bindings on non-existent level
929+ /// assert_eq!(reader.resolver().bindings_of(5).collect::<Vec<_>>(), vec![]);
930+ /// # quick_xml::Result::Ok(())
931+ /// ```
932+ ///
933+ /// [current]: Self::level
934+ pub const fn bindings_of ( & self , level : u16 ) -> NamespaceBindingsOfLevelIter < ' _ > {
935+ NamespaceBindingsOfLevelIter {
936+ resolver : self ,
937+ cursor : 0 ,
938+ level,
939+ }
940+ }
941+
942+ /// Returns the number of [`push`] calls that were not followed by [`pop`] calls.
943+ ///
944+ /// Due to use of `u16` for level number the number of nested tags in XML
945+ /// are limited by [`u16::MAX`], but that is enough for any real application.
946+ ///
947+ /// # Example
948+ ///
949+ /// ```
950+ /// # use pretty_assertions::assert_eq;
951+ /// # use quick_xml::events::BytesStart;
952+ /// # use quick_xml::name::{Namespace, NamespaceResolver, PrefixDeclaration, QName, ResolveResult};
953+ /// #
954+ /// let mut resolver = NamespaceResolver::default();
955+ ///
956+ /// assert_eq!(resolver.level(), 0);
957+ ///
958+ /// resolver.push(&BytesStart::new("tag"));
959+ /// assert_eq!(resolver.level(), 1);
960+ ///
961+ /// resolver.pop();
962+ /// assert_eq!(resolver.level(), 0);
963+ ///
964+ /// // pop from empty resolver does nothing
965+ /// resolver.pop();
966+ /// assert_eq!(resolver.level(), 0);
967+ /// ```
968+ ///
969+ /// [`push`]: Self::push
970+ /// [`pop`]: Self::pop
971+ pub const fn level ( & self ) -> u16 {
972+ self . nesting_level
973+ }
869974}
870975
871976////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -918,6 +1023,50 @@ impl<'a> FusedIterator for NamespaceBindingsIter<'a> {}
9181023#[ deprecated = "Use NamespaceBindingsIter instead" ]
9191024pub type PrefixIter < ' a > = NamespaceBindingsIter < ' a > ;
9201025
1026+ /// Iterator on the declared namespace bindings on specified level. Returns pairs of the _(prefix, namespace)_.
1027+ ///
1028+ /// See [`NamespaceResolver::bindings_of`] for documentation.
1029+ #[ derive( Debug , Clone ) ]
1030+ pub struct NamespaceBindingsOfLevelIter < ' a > {
1031+ resolver : & ' a NamespaceResolver ,
1032+ cursor : usize ,
1033+ level : u16 ,
1034+ }
1035+
1036+ impl < ' a > Iterator for NamespaceBindingsOfLevelIter < ' a > {
1037+ type Item = ( PrefixDeclaration < ' a > , Namespace < ' a > ) ;
1038+
1039+ fn next ( & mut self ) -> Option < ( PrefixDeclaration < ' a > , Namespace < ' a > ) > {
1040+ while let Some ( binding) = self . resolver . bindings . get ( self . cursor ) {
1041+ self . cursor += 1 ; // We increment for next read
1042+ if binding. level < self . level {
1043+ continue ;
1044+ }
1045+ if binding. level > self . level {
1046+ break ;
1047+ }
1048+
1049+ if let ResolveResult :: Bound ( namespace) = binding. namespace ( & self . resolver . buffer ) {
1050+ let prefix = match binding. prefix ( & self . resolver . buffer ) {
1051+ Some ( Prefix ( prefix) ) => PrefixDeclaration :: Named ( prefix) ,
1052+ None => PrefixDeclaration :: Default ,
1053+ } ;
1054+ return Some ( ( prefix, namespace) ) ;
1055+ }
1056+ }
1057+ None // We have exhausted the array
1058+ }
1059+
1060+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
1061+ // Real count could be less
1062+ ( 0 , Some ( self . resolver . bindings . len ( ) - self . cursor ) )
1063+ }
1064+ }
1065+
1066+ impl < ' a > FusedIterator for NamespaceBindingsOfLevelIter < ' a > { }
1067+
1068+ ////////////////////////////////////////////////////////////////////////////////////////////////////
1069+
9211070#[ cfg( test) ]
9221071mod namespaces {
9231072 use super :: * ;
0 commit comments