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

Help serializing empty attributes

Open thebeekeeper opened this issue 4 years ago • 1 comments

I have an externally defined XML standard I'm trying to write to which includes requiring empty attribute values. As an example, I need to write the following:

<TIM A="" D="4">

Where my A attribute needs to be written with an empty value, and D needs a constant value. Is it possible to achieve this with the crate using the serde serialize feature? Ideally, I'd like to use an Option like this:

#[derive(Serialize, Debug)]
struct Tim {
   a: Option<String>,
   b: u8,
}

But when I do that, and set a to None, the A attribute isn't serialized at all. I'm not sure that the crate would be able to decide whether or not to serialize the attribute, so I'm guessing I'll need serialize_with. Also tried that, but haven't been able to get it to write out an empty attribute value. The closest I've gotten is writing out <TIM A=" " D="4"/> but in my case, the space in the A attribute value is invalid.

thebeekeeper avatar Jan 11 '21 21:01 thebeekeeper

I have experienced a similar issue to @thebeekeeper, the only difference is that it occurs during deserialization. I would expect the <Foo val="" /> to be mapped to Some("") rather than None, but that does not seem to be the case.

#[derive(Debug, Deserialize, PartialEq)]
struct Foo {
    val: Option<String>,
}

#[test]
fn empty_string() {
    let s = r#""<Foo val=""/>""#;
    let foo: Foo = quick_xml::de::from_str(s).unwrap();
    assert!(foo.val.is_some());
}

clegaard avatar Aug 29 '21 08:08 clegaard

Hi, sorry for commenting on this old issue. Just wondering if you found a solution @thebeekeeper for your example?

<TIM A="" D="4">

I'm in the need to send an empty attribute A="" to an API, and can't figure out how to do it. I tried using NoneAsEmptyString from the serde_with crate, but no luck:

#[derive(Debug, Serialize, Eq, PartialEq)]
#[serde_as]
struct {
  #[serde_as(as = "NoneAsEmptyString")]
  A: Option<String>,
  D: u8,
}

Also tried to do a custom Serialization, but serde removes the attribute if it's none.

TIA

dsegovia90 avatar Nov 04 '22 01:11 dsegovia90