quick-xml icon indicating copy to clipboard operation
quick-xml copied to clipboard

Impossible to serialize and/or deserialize reserved xml attributes.

Open jespersm opened this issue 11 months ago • 1 comments

Roundtripping a xml:lang attribute on an element is not possible.

Example:

#[derive(Debug, PartialEq, Deserialize, Serialize)]
struct ElementWithXmlLang {
    #[serde(rename = "$text")]
    body: &'static str,
    #[serde(rename = "@xml:lang")]
    lang: &'static str,
}

// ...

serialize_as!(xml_lang_attribute: ElementWithXmlLang { body: "Ikke for sarte sjæle", lang: "da" }
                => "<root xml:lang=\"da\">Ikke for sarte sjæle</root>");                    

This serializes correctly, but fail to deserialize (deserialization roundtrip: Custom("missing field '@xml:lang'")), since the element has its 'xml' prefix stripped by the key handling inside key.rs (QNameDeserializer::from_attr), likely introduced when adressing #537.

Since the namespace handling is incomplete anyways (see my suggestions in #218), it would make sense to allow the 'xml' namespace to pass through so the example above could roundtrip.

Using #[serde(rename = "@lang")] works for deserializing, but is not desirable, since it allows unqualified names to go through, too.

jespersm avatar Jan 18 '25 23:01 jespersm

Yes, probably xml prefix in elements and attributes should always be considered as part of a name, because:

  • the xml prefix cannot be bound to any namespace other than http://www.w3.org/XML/1998/namespace
  • the http://www.w3.org/XML/1998/namespace can be bound only to the xml prefix

So, in any XML fragment (except with namespace http://www.w3.org/XML/1998/namespace) the only way to access attributes from the http://www.w3.org/XML/1998/namespace namespace is to literally use the xml:... name. The same is applied to the xmlns prefix too.

PR for implementing this is welcome!

Mingun avatar Jan 19 '25 13:01 Mingun