diff options
Diffstat (limited to 'src/reader.rs')
-rw-r--r-- | src/reader.rs | 94 |
1 files changed, 63 insertions, 31 deletions
diff --git a/src/reader.rs b/src/reader.rs index a05e73b..abc3354 100644 --- a/src/reader.rs +++ b/src/reader.rs @@ -392,51 +392,49 @@ impl<R> Reader<R> { fn end_tag_from_xml( depth: &mut Vec<Name>, - namespaces: &mut Vec<HashSet<NamespaceDeclaration>>, - e_tag: xml::ETag, + namespace_declarations: &mut Vec<HashSet<NamespaceDeclaration>>, + xml_e_tag: xml::ETag, ) -> Result<()> { if let Some(s_tag_name) = depth.pop() { - let (namespace, name); - let namespace_declarations: Vec<_> = namespaces.iter().flatten().collect(); - match e_tag.name { - xml::QName::PrefixedName(ref prefixed_name) => { - namespace = namespace_declarations + let e_tag_namespace_declaration; + let e_tag_local_name = xml_e_tag.name.local_part().to_string(); + let namespace_declarations_stack: Vec<_> = + namespace_declarations.iter().flatten().collect(); + + match xml_e_tag.name.prefix() { + Some(prefix) => { + e_tag_namespace_declaration = namespace_declarations_stack .iter() - .rfind(|namespace| { - namespace.prefix.as_deref() == Some(**prefixed_name.prefix) - }) - .map(|namespace_decl| namespace_decl.namespace.clone()) - .ok_or_else(|| { - return Error::UnqualifiedNamespace((&e_tag.name).to_string()); - })?; - name = prefixed_name.local_part.to_string(); + .rfind(|namespace| namespace.prefix.as_deref() == Some(prefix)); } - xml::QName::UnprefixedName(ref unprefixed_name) => { - namespace = namespace_declarations + None => { + e_tag_namespace_declaration = namespace_declarations_stack .iter() - .rfind(|namespace| namespace.prefix.as_deref() == None) - .map(|namespace_decl| namespace_decl.namespace.clone()) - .ok_or_else(|| { - return Error::UnqualifiedNamespace(e_tag.name.to_string()); - })?; - name = unprefixed_name.to_string(); + .rfind(|namespace| namespace.prefix == None); } } + + let e_tag_namespace = e_tag_namespace_declaration + .ok_or_else(|| Error::UnqualifiedNamespace(xml_e_tag.name.to_string()))? + .namespace + .clone(); + let e_tag_name = Name { - namespace, - local_name: name, + namespace: e_tag_namespace, + local_name: e_tag_local_name, }; + + if e_tag_name != s_tag_name { + return Err(Error::MismatchedEndTag(s_tag_name, e_tag_name)); + } if s_tag_name == e_tag_name { - namespaces.pop(); + namespace_declarations.pop(); return Ok(()); } else { - return Err(Error::MismatchedEndTag( - s_tag_name.local_name, - e_tag.name.to_string(), - )); + return Err(Error::MismatchedEndTag(s_tag_name, e_tag_name)); } } else { - return Err(Error::NotInElement(e_tag.name.to_string())); + return Err(Error::NotInElement(xml_e_tag.name.to_string())); } } @@ -524,6 +522,40 @@ impl<R> Reader<R> { local_name: element_local_name, }; + // end tag name match check + + if let Some(xml_e_name) = xml_e_name { + let e_tag_namespace_declaration; + let e_tag_local_name = xml_e_name.local_part().to_string(); + + match xml_e_name.prefix() { + Some(prefix) => { + e_tag_namespace_declaration = namespace_declarations_stack + .iter() + .rfind(|namespace| namespace.prefix.as_deref() == Some(prefix)); + } + None => { + e_tag_namespace_declaration = namespace_declarations_stack + .iter() + .rfind(|namespace| namespace.prefix == None); + } + } + + let e_tag_namespace = e_tag_namespace_declaration + .ok_or_else(|| Error::UnqualifiedNamespace(xml_name.to_string()))? + .namespace + .clone(); + + let e_tag_name = Name { + namespace: e_tag_namespace, + local_name: e_tag_local_name, + }; + + if e_tag_name != element_name { + return Err(Error::MismatchedEndTag(element_name, e_tag_name)); + } + } + // attributes let mut attributes = HashMap::new(); |