diff --git a/parsers/src/util/macro_tests.rs b/parsers/src/util/macro_tests.rs index 70bbffb90979a522a5c35ed135f3353cbb7aa87f..a477ed9495478865fcdc96bb0bcaa984cbf01d69 100644 --- a/parsers/src/util/macro_tests.rs +++ b/parsers/src/util/macro_tests.rs @@ -139,6 +139,23 @@ fn empty_unexpected_attribute() { } } +#[test] +#[cfg_attr( + feature = "disable-validation", + should_panic = "unexpected result: Ok(" +)] +fn empty_ignores_xml_lang() { + #[allow(unused_imports)] + use core::{ + option::Option::{None, Some}, + result::Result::{Err, Ok}, + }; + match parse_str::("") { + Ok(Empty) => (), + other => panic!("unexpected result: {:?}", other), + } +} + #[test] #[cfg_attr( feature = "disable-validation", diff --git a/xso-proc/src/compound.rs b/xso-proc/src/compound.rs index bf149119932d4e15b4785cbe673fd3edfba1ee2f..d91fa8c3a5244afcb623e17d61faec5974d8ea0b 100644 --- a/xso-proc/src/compound.rs +++ b/xso-proc/src/compound.rs @@ -396,7 +396,11 @@ impl Compound { } } - let mut discard_attr = TokenStream::default(); + // We always implicitly discard the `xml:lang` attribute. Its + // processing is handled using the `#[xml(language)]` meta. + let mut discard_attr = quote! { + let _ = #attrs.remove(::xso::exports::rxml::Namespace::xml(), "lang"); + }; for (xml_namespace, xml_name) in self.discard_attr.iter() { let xml_namespace = match xml_namespace { Some(v) => v.to_token_stream(), diff --git a/xso/ChangeLog b/xso/ChangeLog index f00527a662f386444d2c3609f7d0dd369a4aed61..002c8236c57d6ac501b4c36082f22fcb618c8282 100644 --- a/xso/ChangeLog +++ b/xso/ChangeLog @@ -12,6 +12,11 @@ Version NEXT: This change overall allows for more flexibility in the implementation of text codecs. + - `xml:lang` attributes are now silently discarded during + deserialisation unless captured by `#[xml(attribute = "xml:lang")]` or + equivalent. This is because `xml:lang` is special as per + XML 1.0 § 2.12 and it is generally preferable to allow it to occur + anywhere in the document. * Added - Support for child elements in derive macros. Child elements may also be wrapped in Option or Box or in containers like Vec or HashSet.