Skip to content

Commit 9f1a557

Browse files
committed
Add NamespaceResolver::resolve_event
1 parent cf4f19d commit 9f1a557

File tree

3 files changed

+65
-43
lines changed

3 files changed

+65
-43
lines changed

src/name.rs

Lines changed: 59 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
//! [spec]: https://www.w3.org/TR/xml-names11
55
66
use crate::events::attributes::Attribute;
7-
use crate::events::BytesStart;
7+
use crate::events::{BytesStart, Event};
88
use crate::utils::write_byte_string;
99
use memchr::memchr;
1010
use std::fmt::{self, Debug, Formatter};
@@ -689,19 +689,67 @@ impl NamespaceResolver {
689689
self.resolve(name, false)
690690
}
691691

692-
/// Finds a [namespace name] for a given qualified **element name**, borrow
693-
/// it from the internal buffer.
692+
/// Finds a [namespace name] for a given event, if applicable.
694693
///
695-
/// Returns `None`, if:
696-
/// - name is unqualified
697-
/// - prefix not found in the current scope
698-
/// - prefix was [unbound] using `xmlns:prefix=""`
694+
/// Namespace is resolved only for [`Start`], [`Empty`] and [`End`] events.
695+
/// For all other events the concept of namespace is not defined, so
696+
/// a [`ResolveResult::Unbound`] is returned.
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+
/// let event = reader.read_event().unwrap();
718+
/// match reader.resolver().resolve_event(event) {
719+
/// (Bound(Namespace(b"www.xxxx")), Event::Start(e)) => {
720+
/// count += 1;
721+
/// assert_eq!(e.local_name(), QName(b"tag1").into());
722+
/// }
723+
/// (Bound(Namespace(b"www.yyyy")), Event::Start(e)) => {
724+
/// count += 1;
725+
/// assert_eq!(e.local_name(), QName(b"tag2").into());
726+
/// }
727+
/// (_, Event::Start(_)) => unreachable!(),
728+
///
729+
/// (_, Event::Text(e)) => {
730+
/// txt.push(e.decode().unwrap().into_owned())
731+
/// }
732+
/// (_, Event::Eof) => break,
733+
/// _ => (),
734+
/// }
735+
/// }
736+
/// assert_eq!(count, 3);
737+
/// assert_eq!(txt, vec!["Test".to_string(), "Test 2".to_string()]);
738+
/// ```
699739
///
700740
/// [namespace name]: https://www.w3.org/TR/xml-names11/#dt-NSName
701-
/// [unbound]: https://www.w3.org/TR/xml-names11/#scoping
702-
#[inline]
703-
pub fn find(&self, element_name: QName) -> ResolveResult<'_> {
704-
self.resolve_prefix(element_name.prefix(), true)
741+
/// [`Empty`]: Event::Empty
742+
/// [`Start`]: Event::Start
743+
/// [`End`]: Event::End
744+
pub fn resolve_event<'i>(&self, event: Event<'i>) -> (ResolveResult<'_>, Event<'i>) {
745+
use Event::*;
746+
747+
match event {
748+
Empty(e) => (self.resolve_prefix(e.name().prefix(), true), Empty(e)),
749+
Start(e) => (self.resolve_prefix(e.name().prefix(), true), Start(e)),
750+
End(e) => (self.resolve_prefix(e.name().prefix(), true), End(e)),
751+
e => (ResolveResult::Unbound, e),
752+
}
705753
}
706754

707755
/// Resolves given optional prefix (usually got from [`QName`]) into a corresponding namespace.
@@ -915,7 +963,6 @@ mod namespaces {
915963
resolver.resolve(name, false),
916964
(Unbound, LocalName(b"simple"))
917965
);
918-
assert_eq!(resolver.find(name), Bound(ns));
919966
}
920967

921968
/// Test adding a second level of namespaces, which replaces the previous binding
@@ -944,7 +991,6 @@ mod namespaces {
944991
resolver.resolve(name, false),
945992
(Unbound, LocalName(b"simple"))
946993
);
947-
assert_eq!(resolver.find(name), Bound(new_ns));
948994

949995
resolver.pop();
950996
assert_eq!(&resolver.buffer[s..], b"old");
@@ -956,7 +1002,6 @@ mod namespaces {
9561002
resolver.resolve(name, false),
9571003
(Unbound, LocalName(b"simple"))
9581004
);
959-
assert_eq!(resolver.find(name), Bound(old_ns));
9601005
}
9611006

9621007
/// Test adding a second level of namespaces, which reset the previous binding
@@ -987,7 +1032,6 @@ mod namespaces {
9871032
resolver.resolve(name, false),
9881033
(Unbound, LocalName(b"simple"))
9891034
);
990-
assert_eq!(resolver.find(name), Unbound);
9911035

9921036
resolver.pop();
9931037
assert_eq!(&resolver.buffer[s..], b"old");
@@ -999,7 +1043,6 @@ mod namespaces {
9991043
resolver.resolve(name, false),
10001044
(Unbound, LocalName(b"simple"))
10011045
);
1002-
assert_eq!(resolver.find(name), Bound(old_ns));
10031046
}
10041047
}
10051048

@@ -1035,7 +1078,6 @@ mod namespaces {
10351078
resolver.resolve(name, false),
10361079
(Bound(ns), LocalName(b"with-declared-prefix"))
10371080
);
1038-
assert_eq!(resolver.find(name), Bound(ns));
10391081
}
10401082

10411083
/// Test adding a second level of namespaces, which replaces the previous binding
@@ -1064,7 +1106,6 @@ mod namespaces {
10641106
resolver.resolve(name, false),
10651107
(Bound(new_ns), LocalName(b"with-declared-prefix"))
10661108
);
1067-
assert_eq!(resolver.find(name), Bound(new_ns));
10681109

10691110
resolver.pop();
10701111
assert_eq!(&resolver.buffer[s..], b"pold");
@@ -1076,7 +1117,6 @@ mod namespaces {
10761117
resolver.resolve(name, false),
10771118
(Bound(old_ns), LocalName(b"with-declared-prefix"))
10781119
);
1079-
assert_eq!(resolver.find(name), Bound(old_ns));
10801120
}
10811121

10821122
/// Test adding a second level of namespaces, which reset the previous binding
@@ -1107,7 +1147,6 @@ mod namespaces {
11071147
resolver.resolve(name, false),
11081148
(Unknown(b"p".to_vec()), LocalName(b"with-declared-prefix"))
11091149
);
1110-
assert_eq!(resolver.find(name), Unknown(b"p".to_vec()));
11111150

11121151
resolver.pop();
11131152
assert_eq!(&resolver.buffer[s..], b"pold");
@@ -1119,7 +1158,6 @@ mod namespaces {
11191158
resolver.resolve(name, false),
11201159
(Bound(old_ns), LocalName(b"with-declared-prefix"))
11211160
);
1122-
assert_eq!(resolver.find(name), Bound(old_ns));
11231161
}
11241162
}
11251163

@@ -1150,7 +1188,6 @@ mod namespaces {
11501188
resolver.resolve(name, false),
11511189
(Bound(namespace), LocalName(b"random"))
11521190
);
1153-
assert_eq!(resolver.find(name), Bound(namespace));
11541191
}
11551192

11561193
/// `xml` prefix can be declared but it must be bound to the value
@@ -1234,7 +1271,6 @@ mod namespaces {
12341271
resolver.resolve(name, false),
12351272
(Bound(namespace), LocalName(b"random"))
12361273
);
1237-
assert_eq!(resolver.find(name), Bound(namespace));
12381274
}
12391275

12401276
/// `xmlns` prefix cannot be re-declared event to its own namespace
@@ -1318,7 +1354,6 @@ mod namespaces {
13181354
resolver.resolve(name, false),
13191355
(Unknown(b"unknown".to_vec()), LocalName(b"prefix"))
13201356
);
1321-
assert_eq!(resolver.find(name), Unknown(b"unknown".to_vec()));
13221357
}
13231358

13241359
/// Checks how the QName is decomposed to a prefix and a local name

src/reader/async_tokio.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -406,8 +406,8 @@ impl<R: AsyncBufRead + Unpin> NsReader<R> {
406406
&'ns mut self,
407407
buf: &'b mut Vec<u8>,
408408
) -> Result<(ResolveResult<'ns>, Event<'b>)> {
409-
let event = self.read_event_into_async(buf).await;
410-
self.resolve_event(event)
409+
let event = self.read_event_into_async(buf).await?;
410+
Ok(self.resolver().resolve_event(event))
411411
}
412412
}
413413

src/reader/ns_reader.rs

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -184,19 +184,6 @@ impl<R> NsReader<R> {
184184
e => e,
185185
}
186186
}
187-
188-
pub(super) fn resolve_event<'i>(
189-
&mut self,
190-
event: Result<Event<'i>>,
191-
) -> Result<(ResolveResult<'_>, Event<'i>)> {
192-
match event {
193-
Ok(Event::Start(e)) => Ok((self.ns_resolver.find(e.name()), Event::Start(e))),
194-
Ok(Event::Empty(e)) => Ok((self.ns_resolver.find(e.name()), Event::Empty(e))),
195-
Ok(Event::End(e)) => Ok((self.ns_resolver.find(e.name()), Event::End(e))),
196-
Ok(e) => Ok((ResolveResult::Unbound, e)),
197-
Err(e) => Err(e),
198-
}
199-
}
200187
}
201188

202189
/// Getters
@@ -508,8 +495,8 @@ impl<R: BufRead> NsReader<R> {
508495
&mut self,
509496
buf: &'b mut Vec<u8>,
510497
) -> Result<(ResolveResult<'_>, Event<'b>)> {
511-
let event = self.read_event_impl(buf);
512-
self.resolve_event(event)
498+
let event = self.read_event_impl(buf)?;
499+
Ok(self.ns_resolver.resolve_event(event))
513500
}
514501

515502
/// Reads until end element is found using provided buffer as intermediate
@@ -752,8 +739,8 @@ impl<'i> NsReader<&'i [u8]> {
752739
/// [`read_event()`]: Self::read_event
753740
#[inline]
754741
pub fn read_resolved_event(&mut self) -> Result<(ResolveResult<'_>, Event<'i>)> {
755-
let event = self.read_event_impl(());
756-
self.resolve_event(event)
742+
let event = self.read_event_impl(())?;
743+
Ok(self.ns_resolver.resolve_event(event))
757744
}
758745

759746
/// Reads until end element is found. This function is supposed to be called

0 commit comments

Comments
 (0)