@@ -23,6 +23,52 @@ impl<'a> QName<'a> {
2323 self . 0
2424 }
2525
26+ /// Returns local part of this qualified name.
27+ ///
28+ /// All content up to and including the first `:` character is removed from
29+ /// the tag name.
30+ ///
31+ /// # Examples
32+ ///
33+ /// ```
34+ /// # use quick_xml::name::QName;
35+ /// let simple = QName(b"simple-name");
36+ /// assert_eq!(simple.local_name().as_ref(), b"simple-name");
37+ ///
38+ /// let qname = QName(b"namespace:simple-name");
39+ /// assert_eq!(qname.local_name().as_ref(), b"simple-name");
40+ /// ```
41+ pub fn local_name ( & self ) -> LocalName < ' a > {
42+ LocalName ( self . index ( ) . map_or ( self . 0 , |i| & self . 0 [ i + 1 ..] ) )
43+ }
44+
45+ /// Returns namespace part of this qualified name or `None` if namespace part
46+ /// is not defined (symbol `':'` not found).
47+ ///
48+ /// # Examples
49+ ///
50+ /// ```
51+ /// # use std::convert::AsRef;
52+ /// # use quick_xml::name::QName;
53+ /// let simple = QName(b"simple-name");
54+ /// assert_eq!(simple.prefix(), None);
55+ ///
56+ /// let qname = QName(b"prefix:simple-name");
57+ /// assert_eq!(qname.prefix().as_ref().map(|n| n.as_ref()), Some(b"prefix".as_ref()));
58+ /// ```
59+ pub fn prefix ( & self ) -> Option < Prefix < ' a > > {
60+ self . index ( ) . map ( |i| Prefix ( & self . 0 [ ..i] ) )
61+ }
62+
63+ /// The same as `(qname.local_name(), qname.prefix())`, but does only one
64+ /// lookup for a `':'` symbol.
65+ pub fn decompose ( & self ) -> ( LocalName < ' a > , Option < Prefix < ' a > > ) {
66+ match self . index ( ) {
67+ None => ( LocalName ( self . 0 ) , None ) ,
68+ Some ( i) => ( LocalName ( & self . 0 [ i + 1 ..] ) , Some ( Prefix ( & self . 0 [ ..i] ) ) ) ,
69+ }
70+ }
71+
2672 /// Returns the index in the name where prefix ended
2773 #[ inline( always) ]
2874 fn index ( & self ) -> Option < usize > {
@@ -214,6 +260,17 @@ struct NamespaceEntry {
214260}
215261
216262impl NamespaceEntry {
263+ /// Get the namespace prefix, bound to this namespace declaration, or `None`,
264+ /// if this declaration is for default namespace (`xmlns="..."`).
265+ #[ inline]
266+ fn prefix < ' b > ( & self , ns_buffer : & ' b [ u8 ] ) -> Option < Prefix < ' b > > {
267+ if self . prefix_len == 0 {
268+ None
269+ } else {
270+ Some ( Prefix ( & ns_buffer[ self . start ..self . start + self . prefix_len ] ) )
271+ }
272+ }
273+
217274 /// Gets the namespace name (the URI) slice out of namespace buffer
218275 ///
219276 /// Returns `None` if namespace for this prefix was explicitly removed from
@@ -231,12 +288,14 @@ impl NamespaceEntry {
231288 /// Check if the namespace matches the potentially qualified name
232289 #[ inline]
233290 fn is_match ( & self , buffer : & [ u8 ] , name : QName ) -> bool {
234- let qname = name. into_inner ( ) ;
235- if self . prefix_len == 0 {
236- !qname. contains ( & b':' )
237- } else {
238- qname. get ( self . prefix_len ) . map_or ( false , |n| * n == b':' )
239- && qname. starts_with ( & buffer[ self . start ..self . start + self . prefix_len ] )
291+ match ( self . prefix ( buffer) , name. prefix ( ) ) {
292+ // If both parts has no prefixes -> matched
293+ ( None , None ) => true ,
294+ // If one part has prefix but other is not -> not matched
295+ ( None , Some ( _) ) => false ,
296+ ( Some ( _) , None ) => false ,
297+ // Otherwise check that prefixes the same
298+ ( Some ( definition) , Some ( usage) ) => definition == usage,
240299 }
241300 }
242301}
0 commit comments