quick_xml/reader/
ns_reader.rs

1//! A reader that manages namespace declarations found in the input and able
2//! to resolve [qualified names] to [expanded names].
3//!
4//! [qualified names]: https://www.w3.org/TR/xml-names11/#dt-qualname
5//! [expanded names]: https://www.w3.org/TR/xml-names11/#dt-expname
6
7use std::borrow::Cow;
8use std::fs::File;
9use std::io::{BufRead, BufReader};
10use std::ops::Deref;
11use std::path::Path;
12
13use crate::errors::Result;
14use crate::events::Event;
15use crate::name::{LocalName, NamespaceResolver, PrefixIter, QName, ResolveResult};
16use crate::reader::{Config, Reader, Span, XmlSource};
17
18/// A low level encoding-agnostic XML event reader that performs namespace resolution.
19///
20/// Consumes a [`BufRead`] and streams XML `Event`s.
21pub struct NsReader<R> {
22    /// An XML reader
23    pub(super) reader: Reader<R>,
24    /// A buffer to manage namespaces
25    ns_resolver: NamespaceResolver,
26    /// We cannot pop data from the namespace stack until returned `Empty` or `End`
27    /// event will be processed by the user, so we only mark that we should that
28    /// in the next [`Self::read_event_impl()`] call.
29    pending_pop: bool,
30}
31
32/// Builder methods
33impl<R> NsReader<R> {
34    /// Creates a `NsReader` that reads from a reader.
35    #[inline]
36    pub fn from_reader(reader: R) -> Self {
37        Self::new(Reader::from_reader(reader))
38    }
39
40    /// Returns reference to the parser configuration
41    #[inline]
42    pub const fn config(&self) -> &Config {
43        self.reader.config()
44    }
45
46    /// Returns mutable reference to the parser configuration
47    #[inline]
48    pub fn config_mut(&mut self) -> &mut Config {
49        self.reader.config_mut()
50    }
51
52    /// Returns all the prefixes currently declared except the default `xml` and `xmlns` namespaces.
53    ///
54    /// # Examples
55    ///
56    /// This example shows what results the returned iterator would return after
57    /// reading each event of a simple XML.
58    ///
59    /// ```
60    /// # use pretty_assertions::assert_eq;
61    /// use quick_xml::name::{Namespace, PrefixDeclaration};
62    /// use quick_xml::NsReader;
63    ///
64    /// let src = "<root>
65    ///   <a xmlns=\"a1\" xmlns:a=\"a2\">
66    ///     <b xmlns=\"b1\" xmlns:b=\"b2\">
67    ///       <c/>
68    ///     </b>
69    ///     <d/>
70    ///   </a>
71    /// </root>";
72    /// let mut reader = NsReader::from_str(src);
73    /// reader.config_mut().trim_text(true);
74    /// // No prefixes at the beginning
75    /// assert_eq!(reader.prefixes().collect::<Vec<_>>(), vec![]);
76    ///
77    /// reader.read_resolved_event()?; // <root>
78    /// // No prefixes declared on root
79    /// assert_eq!(reader.prefixes().collect::<Vec<_>>(), vec![]);
80    ///
81    /// reader.read_resolved_event()?; // <a>
82    /// // Two prefixes declared on "a"
83    /// assert_eq!(reader.prefixes().collect::<Vec<_>>(), vec![
84    ///     (PrefixDeclaration::Default, Namespace(b"a1")),
85    ///     (PrefixDeclaration::Named(b"a"), Namespace(b"a2"))
86    /// ]);
87    ///
88    /// reader.read_resolved_event()?; // <b>
89    /// // The default prefix got overridden and new "b" prefix
90    /// assert_eq!(reader.prefixes().collect::<Vec<_>>(), vec![
91    ///     (PrefixDeclaration::Named(b"a"), Namespace(b"a2")),
92    ///     (PrefixDeclaration::Default, Namespace(b"b1")),
93    ///     (PrefixDeclaration::Named(b"b"), Namespace(b"b2"))
94    /// ]);
95    ///
96    /// reader.read_resolved_event()?; // <c/>
97    /// // Still the same
98    /// assert_eq!(reader.prefixes().collect::<Vec<_>>(), vec![
99    ///     (PrefixDeclaration::Named(b"a"), Namespace(b"a2")),
100    ///     (PrefixDeclaration::Default, Namespace(b"b1")),
101    ///     (PrefixDeclaration::Named(b"b"), Namespace(b"b2"))
102    /// ]);
103    ///
104    /// reader.read_resolved_event()?; // </b>
105    /// // Still the same
106    /// assert_eq!(reader.prefixes().collect::<Vec<_>>(), vec![
107    ///     (PrefixDeclaration::Named(b"a"), Namespace(b"a2")),
108    ///     (PrefixDeclaration::Default, Namespace(b"b1")),
109    ///     (PrefixDeclaration::Named(b"b"), Namespace(b"b2"))
110    /// ]);
111    ///
112    /// reader.read_resolved_event()?; // <d/>
113    /// // </b> got closed so back to the prefixes declared on <a>
114    /// assert_eq!(reader.prefixes().collect::<Vec<_>>(), vec![
115    ///     (PrefixDeclaration::Default, Namespace(b"a1")),
116    ///     (PrefixDeclaration::Named(b"a"), Namespace(b"a2"))
117    /// ]);
118    ///
119    /// reader.read_resolved_event()?; // </a>
120    /// // Still the same
121    /// assert_eq!(reader.prefixes().collect::<Vec<_>>(), vec![
122    ///     (PrefixDeclaration::Default, Namespace(b"a1")),
123    ///     (PrefixDeclaration::Named(b"a"), Namespace(b"a2"))
124    /// ]);
125    ///
126    /// reader.read_resolved_event()?; // </root>
127    /// // <a> got closed
128    /// assert_eq!(reader.prefixes().collect::<Vec<_>>(), vec![]);
129    /// # quick_xml::Result::Ok(())
130    /// ```
131    #[inline]
132    pub const fn prefixes(&self) -> PrefixIter {
133        self.ns_resolver.iter()
134    }
135}
136
137/// Private methods
138impl<R> NsReader<R> {
139    #[inline]
140    fn new(reader: Reader<R>) -> Self {
141        Self {
142            reader,
143            ns_resolver: NamespaceResolver::default(),
144            pending_pop: false,
145        }
146    }
147
148    fn read_event_impl<'i, B>(&mut self, buf: B) -> Result<Event<'i>>
149    where
150        R: XmlSource<'i, B>,
151    {
152        self.pop();
153        let event = self.reader.read_event_impl(buf);
154        self.process_event(event)
155    }
156
157    pub(super) fn pop(&mut self) {
158        if self.pending_pop {
159            self.ns_resolver.pop();
160            self.pending_pop = false;
161        }
162    }
163
164    pub(super) fn process_event<'i>(&mut self, event: Result<Event<'i>>) -> Result<Event<'i>> {
165        match event {
166            Ok(Event::Start(e)) => {
167                self.ns_resolver.push(&e)?;
168                Ok(Event::Start(e))
169            }
170            Ok(Event::Empty(e)) => {
171                self.ns_resolver.push(&e)?;
172                // notify next `read_event_impl()` invocation that it needs to pop this
173                // namespace scope
174                self.pending_pop = true;
175                Ok(Event::Empty(e))
176            }
177            Ok(Event::End(e)) => {
178                // notify next `read_event_impl()` invocation that it needs to pop this
179                // namespace scope
180                self.pending_pop = true;
181                Ok(Event::End(e))
182            }
183            e => e,
184        }
185    }
186
187    pub(super) fn resolve_event<'i>(
188        &mut self,
189        event: Result<Event<'i>>,
190    ) -> Result<(ResolveResult, Event<'i>)> {
191        match event {
192            Ok(Event::Start(e)) => Ok((self.ns_resolver.find(e.name()), Event::Start(e))),
193            Ok(Event::Empty(e)) => Ok((self.ns_resolver.find(e.name()), Event::Empty(e))),
194            Ok(Event::End(e)) => Ok((self.ns_resolver.find(e.name()), Event::End(e))),
195            Ok(e) => Ok((ResolveResult::Unbound, e)),
196            Err(e) => Err(e),
197        }
198    }
199}
200
201/// Getters
202impl<R> NsReader<R> {
203    /// Consumes `NsReader` returning the underlying reader
204    ///
205    /// See the [`Reader::into_inner`] for examples
206    #[inline]
207    pub fn into_inner(self) -> R {
208        self.reader.into_inner()
209    }
210
211    /// Gets a mutable reference to the underlying reader.
212    pub fn get_mut(&mut self) -> &mut R {
213        self.reader.get_mut()
214    }
215
216    /// Resolves a potentially qualified **element name** or **attribute name**
217    /// into _(namespace name, local name)_.
218    ///
219    /// _Qualified_ names have the form `prefix:local-name` where the `prefix`
220    /// is defined on any containing XML element via `xmlns:prefix="the:namespace:uri"`.
221    /// The namespace prefix can be defined on the same element as the name in question.
222    ///
223    /// The method returns following results depending on the `name` shape,
224    /// `attribute` flag and the presence of the default namespace:
225    ///
226    /// |attribute|`xmlns="..."`|QName              |ResolveResult          |LocalName
227    /// |---------|-------------|-------------------|-----------------------|------------
228    /// |`true`   |Not defined  |`local-name`       |[`Unbound`]            |`local-name`
229    /// |`true`   |Defined      |`local-name`       |[`Unbound`]            |`local-name`
230    /// |`true`   |_any_        |`prefix:local-name`|[`Bound`] / [`Unknown`]|`local-name`
231    /// |`false`  |Not defined  |`local-name`       |[`Unbound`]            |`local-name`
232    /// |`false`  |Defined      |`local-name`       |[`Bound`] (default)    |`local-name`
233    /// |`false`  |_any_        |`prefix:local-name`|[`Bound`] / [`Unknown`]|`local-name`
234    ///
235    /// If you want to clearly indicate that name that you resolve is an element
236    /// or an attribute name, you could use [`resolve_attribute()`] or [`resolve_element()`]
237    /// methods.
238    ///
239    /// # Lifetimes
240    ///
241    /// - `'n`: lifetime of a name. Returned local name will be bound to the same
242    ///   lifetime as the name in question.
243    /// - returned namespace name will be bound to the reader itself
244    ///
245    /// [`Bound`]: ResolveResult::Bound
246    /// [`Unbound`]: ResolveResult::Unbound
247    /// [`Unknown`]: ResolveResult::Unknown
248    /// [`resolve_attribute()`]: Self::resolve_attribute()
249    /// [`resolve_element()`]: Self::resolve_element()
250    #[inline]
251    pub fn resolve<'n>(&self, name: QName<'n>, attribute: bool) -> (ResolveResult, LocalName<'n>) {
252        self.ns_resolver.resolve(name, !attribute)
253    }
254
255    /// Resolves a potentially qualified **element name** into _(namespace name, local name)_.
256    ///
257    /// _Qualified_ element names have the form `prefix:local-name` where the
258    /// `prefix` is defined on any containing XML element via `xmlns:prefix="the:namespace:uri"`.
259    /// The namespace prefix can be defined on the same element as the element
260    /// in question.
261    ///
262    /// _Unqualified_ elements inherits the current _default namespace_.
263    ///
264    /// The method returns following results depending on the `name` shape and
265    /// the presence of the default namespace:
266    ///
267    /// |`xmlns="..."`|QName              |ResolveResult          |LocalName
268    /// |-------------|-------------------|-----------------------|------------
269    /// |Not defined  |`local-name`       |[`Unbound`]            |`local-name`
270    /// |Defined      |`local-name`       |[`Bound`] (default)    |`local-name`
271    /// |_any_        |`prefix:local-name`|[`Bound`] / [`Unknown`]|`local-name`
272    ///
273    /// # Lifetimes
274    ///
275    /// - `'n`: lifetime of an element name. Returned local name will be bound
276    ///   to the same lifetime as the name in question.
277    /// - returned namespace name will be bound to the reader itself
278    ///
279    /// # Examples
280    ///
281    /// This example shows how you can resolve qualified name into a namespace.
282    /// Note, that in the code like this you do not need to do that manually,
283    /// because the namespace resolution result returned by the [`read_resolved_event()`].
284    ///
285    /// ```
286    /// # use pretty_assertions::assert_eq;
287    /// use quick_xml::events::Event;
288    /// use quick_xml::name::{Namespace, QName, ResolveResult::*};
289    /// use quick_xml::reader::NsReader;
290    ///
291    /// let mut reader = NsReader::from_str("<tag xmlns='root namespace'/>");
292    ///
293    /// match reader.read_event().unwrap() {
294    ///     Event::Empty(e) => assert_eq!(
295    ///         reader.resolve_element(e.name()),
296    ///         (Bound(Namespace(b"root namespace")), QName(b"tag").into())
297    ///     ),
298    ///     _ => unreachable!(),
299    /// }
300    /// ```
301    ///
302    /// [`Bound`]: ResolveResult::Bound
303    /// [`Unbound`]: ResolveResult::Unbound
304    /// [`Unknown`]: ResolveResult::Unknown
305    /// [`read_resolved_event()`]: Self::read_resolved_event
306    #[inline]
307    pub fn resolve_element<'n>(&self, name: QName<'n>) -> (ResolveResult, LocalName<'n>) {
308        self.ns_resolver.resolve(name, true)
309    }
310
311    /// Resolves a potentially qualified **attribute name** into _(namespace name, local name)_.
312    ///
313    /// _Qualified_ attribute names have the form `prefix:local-name` where the
314    /// `prefix` is defined on any containing XML element via `xmlns:prefix="the:namespace:uri"`.
315    /// The namespace prefix can be defined on the same element as the attribute
316    /// in question.
317    ///
318    /// _Unqualified_ attribute names do *not* inherit the current _default namespace_.
319    ///
320    /// The method returns following results depending on the `name` shape and
321    /// the presence of the default namespace:
322    ///
323    /// |`xmlns="..."`|QName              |ResolveResult          |LocalName
324    /// |-------------|-------------------|-----------------------|------------
325    /// |Not defined  |`local-name`       |[`Unbound`]            |`local-name`
326    /// |Defined      |`local-name`       |[`Unbound`]            |`local-name`
327    /// |_any_        |`prefix:local-name`|[`Bound`] / [`Unknown`]|`local-name`
328    ///
329    /// # Lifetimes
330    ///
331    /// - `'n`: lifetime of an attribute name. Returned local name will be bound
332    ///   to the same lifetime as the name in question.
333    /// - returned namespace name will be bound to the reader itself
334    ///
335    /// # Examples
336    ///
337    /// ```
338    /// # use pretty_assertions::assert_eq;
339    /// use quick_xml::events::Event;
340    /// use quick_xml::name::{Namespace, QName, ResolveResult::*};
341    /// use quick_xml::reader::NsReader;
342    ///
343    /// let mut reader = NsReader::from_str("
344    ///     <tag one='1'
345    ///          p:two='2'
346    ///          xmlns='root namespace'
347    ///          xmlns:p='other namespace'/>
348    /// ");
349    /// reader.config_mut().trim_text(true);
350    ///
351    /// match reader.read_event().unwrap() {
352    ///     Event::Empty(e) => {
353    ///         let mut iter = e.attributes();
354    ///
355    ///         // Unlike elements, attributes without explicit namespace
356    ///         // not bound to any namespace
357    ///         let one = iter.next().unwrap().unwrap();
358    ///         assert_eq!(
359    ///             reader.resolve_attribute(one.key),
360    ///             (Unbound, QName(b"one").into())
361    ///         );
362    ///
363    ///         let two = iter.next().unwrap().unwrap();
364    ///         assert_eq!(
365    ///             reader.resolve_attribute(two.key),
366    ///             (Bound(Namespace(b"other namespace")), QName(b"two").into())
367    ///         );
368    ///     }
369    ///     _ => unreachable!(),
370    /// }
371    /// ```
372    ///
373    /// [`Bound`]: ResolveResult::Bound
374    /// [`Unbound`]: ResolveResult::Unbound
375    /// [`Unknown`]: ResolveResult::Unknown
376    #[inline]
377    pub fn resolve_attribute<'n>(&self, name: QName<'n>) -> (ResolveResult, LocalName<'n>) {
378        self.ns_resolver.resolve(name, false)
379    }
380}
381
382impl<R: BufRead> NsReader<R> {
383    /// Reads the next event into given buffer.
384    ///
385    /// This method manages namespaces but doesn't resolve them automatically.
386    /// You should call [`resolve_element()`] if you want to get a namespace.
387    ///
388    /// You also can use [`read_resolved_event_into()`] instead if you want to resolve
389    /// namespace as soon as you get an event.
390    ///
391    /// # Examples
392    ///
393    /// ```
394    /// # use pretty_assertions::assert_eq;
395    /// use quick_xml::events::Event;
396    /// use quick_xml::name::{Namespace, ResolveResult::*};
397    /// use quick_xml::reader::NsReader;
398    ///
399    /// let mut reader = NsReader::from_str(r#"
400    ///     <x:tag1 xmlns:x="www.xxxx" xmlns:y="www.yyyy" att1 = "test">
401    ///        <y:tag2><!--Test comment-->Test</y:tag2>
402    ///        <y:tag2>Test 2</y:tag2>
403    ///     </x:tag1>
404    /// "#);
405    /// reader.config_mut().trim_text(true);
406    ///
407    /// let mut count = 0;
408    /// let mut buf = Vec::new();
409    /// let mut txt = Vec::new();
410    /// loop {
411    ///     match reader.read_event_into(&mut buf).unwrap() {
412    ///         Event::Start(e) => {
413    ///             count += 1;
414    ///             let (ns, local) = reader.resolve_element(e.name());
415    ///             match local.as_ref() {
416    ///                 b"tag1" => assert_eq!(ns, Bound(Namespace(b"www.xxxx"))),
417    ///                 b"tag2" => assert_eq!(ns, Bound(Namespace(b"www.yyyy"))),
418    ///                 _ => unreachable!(),
419    ///             }
420    ///         }
421    ///         Event::Text(e) => {
422    ///             txt.push(e.unescape().unwrap().into_owned())
423    ///         }
424    ///         Event::Eof => break,
425    ///         _ => (),
426    ///     }
427    ///     buf.clear();
428    /// }
429    /// assert_eq!(count, 3);
430    /// assert_eq!(txt, vec!["Test".to_string(), "Test 2".to_string()]);
431    /// ```
432    ///
433    /// [`resolve_element()`]: Self::resolve_element
434    /// [`read_resolved_event_into()`]: Self::read_resolved_event_into
435    #[inline]
436    pub fn read_event_into<'b>(&mut self, buf: &'b mut Vec<u8>) -> Result<Event<'b>> {
437        self.read_event_impl(buf)
438    }
439
440    /// Reads the next event into given buffer and resolves its namespace (if applicable).
441    ///
442    /// Namespace is resolved only for [`Start`], [`Empty`] and [`End`] events.
443    /// For all other events the concept of namespace is not defined, so
444    /// a [`ResolveResult::Unbound`] is returned.
445    ///
446    /// If you are not interested in namespaces, you can use [`read_event_into()`]
447    /// which will not automatically resolve namespaces for you.
448    ///
449    /// # Examples
450    ///
451    /// ```
452    /// # use pretty_assertions::assert_eq;
453    /// use quick_xml::events::Event;
454    /// use quick_xml::name::{Namespace, QName, ResolveResult::*};
455    /// use quick_xml::reader::NsReader;
456    ///
457    /// let mut reader = NsReader::from_str(r#"
458    ///     <x:tag1 xmlns:x="www.xxxx" xmlns:y="www.yyyy" att1 = "test">
459    ///        <y:tag2><!--Test comment-->Test</y:tag2>
460    ///        <y:tag2>Test 2</y:tag2>
461    ///     </x:tag1>
462    /// "#);
463    /// reader.config_mut().trim_text(true);
464    ///
465    /// let mut count = 0;
466    /// let mut buf = Vec::new();
467    /// let mut txt = Vec::new();
468    /// loop {
469    ///     match reader.read_resolved_event_into(&mut buf).unwrap() {
470    ///         (Bound(Namespace(b"www.xxxx")), Event::Start(e)) => {
471    ///             count += 1;
472    ///             assert_eq!(e.local_name(), QName(b"tag1").into());
473    ///         }
474    ///         (Bound(Namespace(b"www.yyyy")), Event::Start(e)) => {
475    ///             count += 1;
476    ///             assert_eq!(e.local_name(), QName(b"tag2").into());
477    ///         }
478    ///         (_, Event::Start(_)) => unreachable!(),
479    ///
480    ///         (_, Event::Text(e)) => {
481    ///             txt.push(e.unescape().unwrap().into_owned())
482    ///         }
483    ///         (_, Event::Eof) => break,
484    ///         _ => (),
485    ///     }
486    ///     buf.clear();
487    /// }
488    /// assert_eq!(count, 3);
489    /// assert_eq!(txt, vec!["Test".to_string(), "Test 2".to_string()]);
490    /// ```
491    ///
492    /// [`Start`]: Event::Start
493    /// [`Empty`]: Event::Empty
494    /// [`End`]: Event::End
495    /// [`read_event_into()`]: Self::read_event_into
496    #[inline]
497    pub fn read_resolved_event_into<'b>(
498        &mut self,
499        buf: &'b mut Vec<u8>,
500    ) -> Result<(ResolveResult, Event<'b>)> {
501        let event = self.read_event_impl(buf);
502        self.resolve_event(event)
503    }
504
505    /// Reads until end element is found using provided buffer as intermediate
506    /// storage for events content. This function is supposed to be called after
507    /// you already read a [`Start`] event.
508    ///
509    /// Returns a span that cover content between `>` of an opening tag and `<` of
510    /// a closing tag or an empty slice, if [`expand_empty_elements`] is set and
511    /// this method was called after reading expanded [`Start`] event.
512    ///
513    /// Manages nested cases where parent and child elements have the _literally_
514    /// same name.
515    ///
516    /// If a corresponding [`End`] event is not found, an error of type [`IllFormed`]
517    /// will be returned. In particularly, that error will be returned if you call
518    /// this method without consuming the corresponding [`Start`] event first.
519    ///
520    /// If your reader created from a string slice or byte array slice, it is
521    /// better to use [`read_to_end()`] method, because it will not copy bytes
522    /// into intermediate buffer.
523    ///
524    /// The provided `buf` buffer will be filled only by one event content at time.
525    /// Before reading of each event the buffer will be cleared. If you know an
526    /// appropriate size of each event, you can preallocate the buffer to reduce
527    /// number of reallocations.
528    ///
529    /// The `end` parameter should contain name of the end element _in the reader
530    /// encoding_. It is good practice to always get that parameter using
531    /// [`BytesStart::to_end()`] method.
532    ///
533    /// # Namespaces
534    ///
535    /// While the `NsReader` does namespace resolution, namespaces does not
536    /// change the algorithm for comparing names. Although the names `a:name`
537    /// and `b:name` where both prefixes `a` and `b` resolves to the same namespace,
538    /// are semantically equivalent, `</b:name>` cannot close `<a:name>`, because
539    /// according to [the specification]
540    ///
541    /// > The end of every element that begins with a **start-tag** MUST be marked
542    /// > by an **end-tag** containing a name that echoes the element's type as
543    /// > given in the **start-tag**
544    ///
545    /// # Examples
546    ///
547    /// This example shows, how you can skip XML content after you read the
548    /// start event.
549    ///
550    /// ```
551    /// # use pretty_assertions::assert_eq;
552    /// use quick_xml::events::{BytesStart, Event};
553    /// use quick_xml::name::{Namespace, ResolveResult};
554    /// use quick_xml::reader::NsReader;
555    ///
556    /// let mut reader = NsReader::from_str(r#"
557    ///     <outer xmlns="namespace 1">
558    ///         <inner xmlns="namespace 2">
559    ///             <outer></outer>
560    ///         </inner>
561    ///         <inner>
562    ///             <inner></inner>
563    ///             <inner/>
564    ///             <outer></outer>
565    ///             <p:outer xmlns:p="ns"></p:outer>
566    ///             <outer/>
567    ///         </inner>
568    ///     </outer>
569    /// "#);
570    /// reader.config_mut().trim_text(true);
571    /// let mut buf = Vec::new();
572    ///
573    /// let ns = Namespace(b"namespace 1");
574    /// let start = BytesStart::from_content(r#"outer xmlns="namespace 1""#, 5);
575    /// let end   = start.to_end().into_owned();
576    ///
577    /// // First, we read a start event...
578    /// assert_eq!(
579    ///     reader.read_resolved_event_into(&mut buf).unwrap(),
580    ///     (ResolveResult::Bound(ns), Event::Start(start))
581    /// );
582    ///
583    /// // ...then, we could skip all events to the corresponding end event.
584    /// // This call will correctly handle nested <outer> elements.
585    /// // Note, however, that this method does not handle namespaces.
586    /// reader.read_to_end_into(end.name(), &mut buf).unwrap();
587    ///
588    /// // At the end we should get an Eof event, because we ate the whole XML
589    /// assert_eq!(
590    ///     reader.read_resolved_event_into(&mut buf).unwrap(),
591    ///     (ResolveResult::Unbound, Event::Eof)
592    /// );
593    /// ```
594    ///
595    /// [`Start`]: Event::Start
596    /// [`End`]: Event::End
597    /// [`IllFormed`]: crate::errors::Error::IllFormed
598    /// [`read_to_end()`]: Self::read_to_end
599    /// [`BytesStart::to_end()`]: crate::events::BytesStart::to_end
600    /// [`expand_empty_elements`]: Config::expand_empty_elements
601    /// [the specification]: https://www.w3.org/TR/xml11/#dt-etag
602    #[inline]
603    pub fn read_to_end_into(&mut self, end: QName, buf: &mut Vec<u8>) -> Result<Span> {
604        // According to the https://www.w3.org/TR/xml11/#dt-etag, end name should
605        // match literally the start name. See `Config::check_end_names` documentation
606        self.reader.read_to_end_into(end, buf)
607    }
608}
609
610impl NsReader<BufReader<File>> {
611    /// Creates an XML reader from a file path.
612    pub fn from_file<P: AsRef<Path>>(path: P) -> Result<Self> {
613        Ok(Self::new(Reader::from_file(path)?))
614    }
615}
616
617impl<'i> NsReader<&'i [u8]> {
618    /// Creates an XML reader from a string slice.
619    #[inline]
620    #[allow(clippy::should_implement_trait)]
621    pub fn from_str(s: &'i str) -> Self {
622        Self::new(Reader::from_str(s))
623    }
624
625    /// Reads the next event, borrow its content from the input buffer.
626    ///
627    /// This method manages namespaces but doesn't resolve them automatically.
628    /// You should call [`resolve_element()`] if you want to get a namespace.
629    ///
630    /// You also can use [`read_resolved_event()`] instead if you want to resolve namespace
631    /// as soon as you get an event.
632    ///
633    /// There is no asynchronous `read_event_async()` version of this function,
634    /// because it is not necessary -- the contents are already in memory and no IO
635    /// is needed, therefore there is no potential for blocking.
636    ///
637    /// # Examples
638    ///
639    /// ```
640    /// # use pretty_assertions::assert_eq;
641    /// use quick_xml::events::Event;
642    /// use quick_xml::name::{Namespace, ResolveResult::*};
643    /// use quick_xml::reader::NsReader;
644    ///
645    /// let mut reader = NsReader::from_str(r#"
646    ///     <x:tag1 xmlns:x="www.xxxx" xmlns:y="www.yyyy" att1 = "test">
647    ///        <y:tag2><!--Test comment-->Test</y:tag2>
648    ///        <y:tag2>Test 2</y:tag2>
649    ///     </x:tag1>
650    /// "#);
651    /// reader.config_mut().trim_text(true);
652    ///
653    /// let mut count = 0;
654    /// let mut txt = Vec::new();
655    /// loop {
656    ///     match reader.read_event().unwrap() {
657    ///         Event::Start(e) => {
658    ///             count += 1;
659    ///             let (ns, local) = reader.resolve_element(e.name());
660    ///             match local.as_ref() {
661    ///                 b"tag1" => assert_eq!(ns, Bound(Namespace(b"www.xxxx"))),
662    ///                 b"tag2" => assert_eq!(ns, Bound(Namespace(b"www.yyyy"))),
663    ///                 _ => unreachable!(),
664    ///             }
665    ///         }
666    ///         Event::Text(e) => {
667    ///             txt.push(e.unescape().unwrap().into_owned())
668    ///         }
669    ///         Event::Eof => break,
670    ///         _ => (),
671    ///     }
672    /// }
673    /// assert_eq!(count, 3);
674    /// assert_eq!(txt, vec!["Test".to_string(), "Test 2".to_string()]);
675    /// ```
676    ///
677    /// [`resolve_element()`]: Self::resolve_element
678    /// [`read_resolved_event()`]: Self::read_resolved_event
679    #[inline]
680    pub fn read_event(&mut self) -> Result<Event<'i>> {
681        self.read_event_impl(())
682    }
683
684    /// Reads the next event, borrow its content from the input buffer, and resolves
685    /// its namespace (if applicable).
686    ///
687    /// Namespace is resolved only for [`Start`], [`Empty`] and [`End`] events.
688    /// For all other events the concept of namespace is not defined, so
689    /// a [`ResolveResult::Unbound`] is returned.
690    ///
691    /// If you are not interested in namespaces, you can use [`read_event()`]
692    /// which will not automatically resolve namespaces for you.
693    ///
694    /// There is no asynchronous `read_resolved_event_async()` version of this function,
695    /// because it is not necessary -- the contents are already in memory and no IO
696    /// is needed, therefore there is no potential for blocking.
697    ///
698    /// # Examples
699    ///
700    /// ```
701    /// # use pretty_assertions::assert_eq;
702    /// use quick_xml::events::Event;
703    /// use quick_xml::name::{Namespace, QName, ResolveResult::*};
704    /// use quick_xml::reader::NsReader;
705    ///
706    /// let mut reader = NsReader::from_str(r#"
707    ///     <x:tag1 xmlns:x="www.xxxx" xmlns:y="www.yyyy" att1 = "test">
708    ///        <y:tag2><!--Test comment-->Test</y:tag2>
709    ///        <y:tag2>Test 2</y:tag2>
710    ///     </x:tag1>
711    /// "#);
712    /// reader.config_mut().trim_text(true);
713    ///
714    /// let mut count = 0;
715    /// let mut txt = Vec::new();
716    /// loop {
717    ///     match reader.read_resolved_event().unwrap() {
718    ///         (Bound(Namespace(b"www.xxxx")), Event::Start(e)) => {
719    ///             count += 1;
720    ///             assert_eq!(e.local_name(), QName(b"tag1").into());
721    ///         }
722    ///         (Bound(Namespace(b"www.yyyy")), Event::Start(e)) => {
723    ///             count += 1;
724    ///             assert_eq!(e.local_name(), QName(b"tag2").into());
725    ///         }
726    ///         (_, Event::Start(_)) => unreachable!(),
727    ///
728    ///         (_, Event::Text(e)) => {
729    ///             txt.push(e.unescape().unwrap().into_owned())
730    ///         }
731    ///         (_, Event::Eof) => break,
732    ///         _ => (),
733    ///     }
734    /// }
735    /// assert_eq!(count, 3);
736    /// assert_eq!(txt, vec!["Test".to_string(), "Test 2".to_string()]);
737    /// ```
738    ///
739    /// [`Start`]: Event::Start
740    /// [`Empty`]: Event::Empty
741    /// [`End`]: Event::End
742    /// [`read_event()`]: Self::read_event
743    #[inline]
744    pub fn read_resolved_event(&mut self) -> Result<(ResolveResult, Event<'i>)> {
745        let event = self.read_event_impl(());
746        self.resolve_event(event)
747    }
748
749    /// Reads until end element is found. This function is supposed to be called
750    /// after you already read a [`Start`] event.
751    ///
752    /// Returns a span that cover content between `>` of an opening tag and `<` of
753    /// a closing tag or an empty slice, if [`expand_empty_elements`] is set and
754    /// this method was called after reading expanded [`Start`] event.
755    ///
756    /// Manages nested cases where parent and child elements have the _literally_
757    /// same name.
758    ///
759    /// If a corresponding [`End`] event is not found, an error of type [`IllFormed`]
760    /// will be returned. In particularly, that error will be returned if you call
761    /// this method without consuming the corresponding [`Start`] event first.
762    ///
763    /// The `end` parameter should contain name of the end element _in the reader
764    /// encoding_. It is good practice to always get that parameter using
765    /// [`BytesStart::to_end()`] method.
766    ///
767    /// There is no asynchronous `read_to_end_async()` version of this function,
768    /// because it is not necessary -- the contents are already in memory and no IO
769    /// is needed, therefore there is no potential for blocking.
770    ///
771    /// # Namespaces
772    ///
773    /// While the `NsReader` does namespace resolution, namespaces does not
774    /// change the algorithm for comparing names. Although the names `a:name`
775    /// and `b:name` where both prefixes `a` and `b` resolves to the same namespace,
776    /// are semantically equivalent, `</b:name>` cannot close `<a:name>`, because
777    /// according to [the specification]
778    ///
779    /// > The end of every element that begins with a **start-tag** MUST be marked
780    /// > by an **end-tag** containing a name that echoes the element's type as
781    /// > given in the **start-tag**
782    ///
783    /// # Examples
784    ///
785    /// This example shows, how you can skip XML content after you read the
786    /// start event.
787    ///
788    /// ```
789    /// # use pretty_assertions::assert_eq;
790    /// use quick_xml::events::{BytesStart, Event};
791    /// use quick_xml::name::{Namespace, ResolveResult};
792    /// use quick_xml::reader::NsReader;
793    ///
794    /// let mut reader = NsReader::from_str(r#"
795    ///     <outer xmlns="namespace 1">
796    ///         <inner xmlns="namespace 2">
797    ///             <outer></outer>
798    ///         </inner>
799    ///         <inner>
800    ///             <inner></inner>
801    ///             <inner/>
802    ///             <outer></outer>
803    ///             <p:outer xmlns:p="ns"></p:outer>
804    ///             <outer/>
805    ///         </inner>
806    ///     </outer>
807    /// "#);
808    /// reader.config_mut().trim_text(true);
809    ///
810    /// let ns = Namespace(b"namespace 1");
811    /// let start = BytesStart::from_content(r#"outer xmlns="namespace 1""#, 5);
812    /// let end   = start.to_end().into_owned();
813    ///
814    /// // First, we read a start event...
815    /// assert_eq!(
816    ///     reader.read_resolved_event().unwrap(),
817    ///     (ResolveResult::Bound(ns), Event::Start(start))
818    /// );
819    ///
820    /// // ...then, we could skip all events to the corresponding end event.
821    /// // This call will correctly handle nested <outer> elements.
822    /// // Note, however, that this method does not handle namespaces.
823    /// reader.read_to_end(end.name()).unwrap();
824    ///
825    /// // At the end we should get an Eof event, because we ate the whole XML
826    /// assert_eq!(
827    ///     reader.read_resolved_event().unwrap(),
828    ///     (ResolveResult::Unbound, Event::Eof)
829    /// );
830    /// ```
831    ///
832    /// [`Start`]: Event::Start
833    /// [`End`]: Event::End
834    /// [`IllFormed`]: crate::errors::Error::IllFormed
835    /// [`BytesStart::to_end()`]: crate::events::BytesStart::to_end
836    /// [`expand_empty_elements`]: Config::expand_empty_elements
837    /// [the specification]: https://www.w3.org/TR/xml11/#dt-etag
838    #[inline]
839    pub fn read_to_end(&mut self, end: QName) -> Result<Span> {
840        // According to the https://www.w3.org/TR/xml11/#dt-etag, end name should
841        // match literally the start name. See `Config::check_end_names` documentation
842        self.reader.read_to_end(end)
843    }
844
845    /// Reads content between start and end tags, including any markup. This
846    /// function is supposed to be called after you already read a [`Start`] event.
847    ///
848    /// Manages nested cases where parent and child elements have the _literally_
849    /// same name.
850    ///
851    /// This method does not unescape read data, instead it returns content
852    /// "as is" of the XML document. This is because it has no idea what text
853    /// it reads, and if, for example, it contains CDATA section, attempt to
854    /// unescape it content will spoil data.
855    ///
856    /// Any text will be decoded using the XML current [`decoder()`].
857    ///
858    /// Actually, this method perform the following code:
859    ///
860    /// ```ignore
861    /// let span = reader.read_to_end(end)?;
862    /// let text = reader.decoder().decode(&reader.inner_slice[span]);
863    /// ```
864    ///
865    /// # Examples
866    ///
867    /// This example shows, how you can read a HTML content from your XML document.
868    ///
869    /// ```
870    /// # use pretty_assertions::assert_eq;
871    /// # use std::borrow::Cow;
872    /// use quick_xml::events::{BytesStart, Event};
873    /// use quick_xml::reader::NsReader;
874    ///
875    /// let mut reader = NsReader::from_str(r#"
876    ///     <html>
877    ///         <title>This is a HTML text</title>
878    ///         <p>Usual XML rules does not apply inside it
879    ///         <p>For example, elements not needed to be &quot;closed&quot;
880    ///     </html>
881    /// "#);
882    /// reader.config_mut().trim_text(true);
883    ///
884    /// let start = BytesStart::new("html");
885    /// let end   = start.to_end().into_owned();
886    ///
887    /// // First, we read a start event...
888    /// assert_eq!(reader.read_event().unwrap(), Event::Start(start));
889    /// // ...and disable checking of end names because we expect HTML further...
890    /// reader.config_mut().check_end_names = false;
891    ///
892    /// // ...then, we could read text content until close tag.
893    /// // This call will correctly handle nested <html> elements.
894    /// let text = reader.read_text(end.name()).unwrap();
895    /// assert_eq!(text, Cow::Borrowed(r#"
896    ///         <title>This is a HTML text</title>
897    ///         <p>Usual XML rules does not apply inside it
898    ///         <p>For example, elements not needed to be &quot;closed&quot;
899    ///     "#));
900    ///
901    /// // Now we can enable checks again
902    /// reader.config_mut().check_end_names = true;
903    ///
904    /// // At the end we should get an Eof event, because we ate the whole XML
905    /// assert_eq!(reader.read_event().unwrap(), Event::Eof);
906    /// ```
907    ///
908    /// [`Start`]: Event::Start
909    /// [`decoder()`]: Reader::decoder()
910    #[inline]
911    pub fn read_text(&mut self, end: QName) -> Result<Cow<'i, str>> {
912        self.reader.read_text(end)
913    }
914}
915
916impl<R> Deref for NsReader<R> {
917    type Target = Reader<R>;
918
919    #[inline]
920    fn deref(&self) -> &Self::Target {
921        &self.reader
922    }
923}