make namespaces optional
This commit is contained in:
		
							parent
							
								
									a3dc4e1475
								
							
						
					
					
						commit
						49c8d52f0d
					
				|  | @ -22,7 +22,7 @@ pub struct NamespaceDeclaration { | ||||||
| // names are qualified, they contain a reference to the namespace (held within the reader/writer)
 | // names are qualified, they contain a reference to the namespace (held within the reader/writer)
 | ||||||
| #[derive(PartialEq, Eq, Hash, Clone, Debug)] | #[derive(PartialEq, Eq, Hash, Clone, Debug)] | ||||||
| pub struct Name { | pub struct Name { | ||||||
|     pub namespace: String, |     pub namespace: Option<String>, | ||||||
|     pub local_name: String, |     pub local_name: String, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -312,7 +312,7 @@ impl<R> Reader<R> { | ||||||
|             .chain(element_namespace_declarations.iter()) |             .chain(element_namespace_declarations.iter()) | ||||||
|             .collect(); |             .collect(); | ||||||
| 
 | 
 | ||||||
|         // element name and default attribute namespace
 |         // element name
 | ||||||
| 
 | 
 | ||||||
|         let element_namespace_declaration; |         let element_namespace_declaration; | ||||||
|         let element_local_name = s_tag.name.local_part().to_string(); |         let element_local_name = s_tag.name.local_part().to_string(); | ||||||
|  | @ -330,10 +330,8 @@ impl<R> Reader<R> { | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         let element_default_namespace = element_namespace_declaration |         let element_default_namespace = | ||||||
|             .ok_or_else(|| Error::UnqualifiedNamespace(s_tag.name.to_string()))? |             element_namespace_declaration.map(|decl| decl.namespace.clone()); | ||||||
|             .namespace |  | ||||||
|             .clone(); |  | ||||||
| 
 | 
 | ||||||
|         let element_name = Name { |         let element_name = Name { | ||||||
|             namespace: element_default_namespace, |             namespace: element_default_namespace, | ||||||
|  | @ -361,20 +359,24 @@ impl<R> Reader<R> { | ||||||
|                                 namespace_declaration.prefix.as_deref() == Some(prefix) |                                 namespace_declaration.prefix.as_deref() == Some(prefix) | ||||||
|                             }); |                             }); | ||||||
|                 } |                 } | ||||||
|                 None => attribute_namespace_declaration = element_namespace_declaration, |                 None => attribute_namespace_declaration = None, | ||||||
|             } |             } | ||||||
|  |             let name; | ||||||
|             if let Some(namespace_declaration) = attribute_namespace_declaration { |             if let Some(namespace_declaration) = attribute_namespace_declaration { | ||||||
|                 let name = Name { |                 name = Name { | ||||||
|                     namespace: namespace_declaration.namespace.clone(), |                     namespace: Some(namespace_declaration.namespace.clone()), | ||||||
|                     local_name: attribute_local_name, |                     local_name: attribute_local_name, | ||||||
|                 }; |                 }; | ||||||
|                 let value = value.process()?; |  | ||||||
|                 // check for duplicate attribute
 |  | ||||||
|                 if let Some(_value) = attributes.insert(name, value) { |  | ||||||
|                     return Err(Error::DuplicateAttribute(q_name.to_string())); |  | ||||||
|                 } |  | ||||||
|             } else { |             } else { | ||||||
|                 return Err(Error::UnqualifiedNamespace(q_name.to_string())); |                 name = Name { | ||||||
|  |                     namespace: None, | ||||||
|  |                     local_name: attribute_local_name, | ||||||
|  |                 }; | ||||||
|  |             } | ||||||
|  |             let value = value.process()?; | ||||||
|  |             // check for duplicate attribute
 | ||||||
|  |             if let Some(_value) = attributes.insert(name, value) { | ||||||
|  |                 return Err(Error::DuplicateAttribute(q_name.to_string())); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | @ -415,8 +417,7 @@ impl<R> Reader<R> { | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             let e_tag_namespace = e_tag_namespace_declaration |             let e_tag_namespace = e_tag_namespace_declaration | ||||||
|                 .ok_or_else(|| Error::UnqualifiedNamespace(xml_e_tag.name.to_string()))? |                 .map(|decl| decl.namespace.clone()) | ||||||
|                 .namespace |  | ||||||
|                 .clone(); |                 .clone(); | ||||||
| 
 | 
 | ||||||
|             let e_tag_name = Name { |             let e_tag_name = Name { | ||||||
|  | @ -512,10 +513,8 @@ impl<R> Reader<R> { | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         let element_default_namespace = element_namespace_declaration |         let element_default_namespace = | ||||||
|             .ok_or_else(|| Error::UnqualifiedNamespace(xml_name.to_string()))? |             element_namespace_declaration.map(|decl| decl.namespace.clone()); | ||||||
|             .namespace |  | ||||||
|             .clone(); |  | ||||||
| 
 | 
 | ||||||
|         let element_name = Name { |         let element_name = Name { | ||||||
|             namespace: element_default_namespace, |             namespace: element_default_namespace, | ||||||
|  | @ -541,10 +540,7 @@ impl<R> Reader<R> { | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             let e_tag_namespace = e_tag_namespace_declaration |             let e_tag_namespace = e_tag_namespace_declaration.map(|decl| decl.namespace.clone()); | ||||||
|                 .ok_or_else(|| Error::UnqualifiedNamespace(xml_name.to_string()))? |  | ||||||
|                 .namespace |  | ||||||
|                 .clone(); |  | ||||||
| 
 | 
 | ||||||
|             let e_tag_name = Name { |             let e_tag_name = Name { | ||||||
|                 namespace: e_tag_namespace, |                 namespace: e_tag_namespace, | ||||||
|  | @ -577,20 +573,24 @@ impl<R> Reader<R> { | ||||||
|                                 namespace_declaration.prefix.as_deref() == Some(prefix) |                                 namespace_declaration.prefix.as_deref() == Some(prefix) | ||||||
|                             }); |                             }); | ||||||
|                 } |                 } | ||||||
|                 None => attribute_namespace_declaration = element_namespace_declaration, |                 None => attribute_namespace_declaration = None, | ||||||
|             } |             } | ||||||
|  |             let name; | ||||||
|             if let Some(namespace_declaration) = attribute_namespace_declaration { |             if let Some(namespace_declaration) = attribute_namespace_declaration { | ||||||
|                 let name = Name { |                 name = Name { | ||||||
|                     namespace: namespace_declaration.namespace.clone(), |                     namespace: Some(namespace_declaration.namespace.clone()), | ||||||
|                     local_name: attribute_local_name, |                     local_name: attribute_local_name, | ||||||
|                 }; |                 }; | ||||||
|                 let value = value.process()?; |  | ||||||
|                 // check for duplicate attribute
 |  | ||||||
|                 if let Some(_value) = attributes.insert(name, value) { |  | ||||||
|                     return Err(Error::DuplicateAttribute(q_name.to_string())); |  | ||||||
|                 } |  | ||||||
|             } else { |             } else { | ||||||
|                 return Err(Error::UnqualifiedNamespace(q_name.to_string())); |                 name = Name { | ||||||
|  |                     namespace: None, | ||||||
|  |                     local_name: attribute_local_name, | ||||||
|  |                 }; | ||||||
|  |             } | ||||||
|  |             let value = value.process()?; | ||||||
|  |             // check for duplicate attribute
 | ||||||
|  |             if let Some(_value) = attributes.insert(name, value) { | ||||||
|  |                 return Err(Error::DuplicateAttribute(q_name.to_string())); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -23,19 +23,24 @@ impl<W: AsyncWrite + Unpin> Writer<W> { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub async fn write_start(&mut self, element: Element) -> Result<()> { |     pub async fn write_start(&mut self, element: Element) -> Result<()> { | ||||||
|         let mut namespace_declarations_stack: Vec<_> = self |         let namespace_declarations_stack: Vec<_> = self | ||||||
|             .namespace_declarations |             .namespace_declarations | ||||||
|             .iter() |             .iter() | ||||||
|             .flatten() |             .flatten() | ||||||
|             .chain(&element.namespace_declarations) |             .chain(&element.namespace_declarations) | ||||||
|             .collect(); |             .collect(); | ||||||
|         let name_namespace_declaration = namespace_declarations_stack | 
 | ||||||
|             .iter() |         let prefix; | ||||||
|             .rfind(|namespace_declaration| { |         if let Some(namespace) = &element.name.namespace { | ||||||
|                 namespace_declaration.namespace == element.name.namespace |             let name_namespace_declaration = namespace_declarations_stack | ||||||
|             }) |                 .iter() | ||||||
|             .ok_or(Error::UndeclaredNamespace(element.name.namespace.clone()))?; |                 .rfind(|namespace_declaration| namespace_declaration.namespace == *namespace) | ||||||
|         let prefix = &name_namespace_declaration.prefix; |                 .ok_or(Error::UndeclaredNamespace(namespace.clone()))?; | ||||||
|  |             prefix = name_namespace_declaration.prefix.as_ref(); | ||||||
|  |         } else { | ||||||
|  |             prefix = None | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         let name; |         let name; | ||||||
|         if let Some(prefix) = &prefix { |         if let Some(prefix) = &prefix { | ||||||
|             name = xml::QName::PrefixedName(xml::PrefixedName { |             name = xml::QName::PrefixedName(xml::PrefixedName { | ||||||
|  | @ -48,8 +53,6 @@ impl<W: AsyncWrite + Unpin> Writer<W> { | ||||||
|             )?) |             )?) | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         namespace_declarations_stack.push(name_namespace_declaration); |  | ||||||
| 
 |  | ||||||
|         let mut attributes = Vec::new(); |         let mut attributes = Vec::new(); | ||||||
| 
 | 
 | ||||||
|         for namespace_declaration in &element.namespace_declarations { |         for namespace_declaration in &element.namespace_declarations { | ||||||
|  | @ -67,6 +70,39 @@ impl<W: AsyncWrite + Unpin> Writer<W> { | ||||||
|             attributes.push(xml_attribute); |             attributes.push(xml_attribute); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         for (name, value) in &element.attributes { | ||||||
|  |             let prefix; | ||||||
|  |             if let Some(namespace) = &name.namespace { | ||||||
|  |                 let name_namespace_declaration = namespace_declarations_stack | ||||||
|  |                     .iter() | ||||||
|  |                     .rfind(|namespace_declaration| namespace_declaration.namespace == *namespace) | ||||||
|  |                     .ok_or(Error::UndeclaredNamespace(namespace.clone()))?; | ||||||
|  |                 prefix = name_namespace_declaration.prefix.as_ref(); | ||||||
|  |             } else { | ||||||
|  |                 prefix = None | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             let att_name; | ||||||
|  |             if let Some(prefix) = &prefix { | ||||||
|  |                 att_name = xml::QName::PrefixedName(xml::PrefixedName { | ||||||
|  |                     prefix: xml::Prefix::parse_full(prefix)?, | ||||||
|  |                     local_part: xml::LocalPart::parse_full(&element.name.local_name)?, | ||||||
|  |                 }) | ||||||
|  |             } else { | ||||||
|  |                 att_name = xml::QName::UnprefixedName(xml::UnprefixedName::parse_full( | ||||||
|  |                     &element.name.local_name, | ||||||
|  |                 )?) | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             let value = xml::AttValue::from(value.as_str()); | ||||||
|  | 
 | ||||||
|  |             let xml_attribute = xml::Attribute::Attribute { | ||||||
|  |                 name: att_name, | ||||||
|  |                 value, | ||||||
|  |             }; | ||||||
|  |             attributes.push(xml_attribute); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         let s_tag = xml::STag { name, attributes }; |         let s_tag = xml::STag { name, attributes }; | ||||||
| 
 | 
 | ||||||
|         s_tag.write(&mut self.inner).await?; |         s_tag.write(&mut self.inner).await?; | ||||||
|  | @ -82,12 +118,18 @@ impl<W: AsyncWrite + Unpin> Writer<W> { | ||||||
|             let e_tag; |             let e_tag; | ||||||
|             let namespace_declarations_stack: Vec<_> = |             let namespace_declarations_stack: Vec<_> = | ||||||
|                 self.namespace_declarations.iter().flatten().collect(); |                 self.namespace_declarations.iter().flatten().collect(); | ||||||
|             let namespace_declaration = namespace_declarations_stack | 
 | ||||||
|                 .iter() |             let prefix; | ||||||
|                 .rfind(|namespace_declaration| namespace_declaration.namespace == name.namespace) |             if let Some(namespace) = &name.namespace { | ||||||
|                 // will always be in this vector
 |                 let name_namespace_declaration = namespace_declarations_stack | ||||||
|                 .unwrap(); |                     .iter() | ||||||
|             let prefix = &namespace_declaration.prefix; |                     .rfind(|namespace_declaration| namespace_declaration.namespace == *namespace) | ||||||
|  |                     .ok_or(Error::UndeclaredNamespace(namespace.clone()))?; | ||||||
|  |                 prefix = name_namespace_declaration.prefix.as_ref(); | ||||||
|  |             } else { | ||||||
|  |                 prefix = None | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|             if let Some(prefix) = &prefix { |             if let Some(prefix) = &prefix { | ||||||
|                 e_tag = xml::ETag { |                 e_tag = xml::ETag { | ||||||
|                     name: xml::QName::PrefixedName(xml::PrefixedName { |                     name: xml::QName::PrefixedName(xml::PrefixedName { | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue