implement end tag match check
This commit is contained in:
parent
c2a84072ac
commit
caf8b7506e
|
@ -13,7 +13,7 @@ pub enum Error {
|
|||
DuplicateNameSpaceDeclaration(NamespaceDeclaration),
|
||||
DuplicateAttribute(String),
|
||||
UnqualifiedNamespace(String),
|
||||
MismatchedEndTag(String, String),
|
||||
MismatchedEndTag(Name, Name),
|
||||
NotInElement(String),
|
||||
ExtraData(String),
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue