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

Documentation unclear on relationship between #[xml(tag)] and #[xml(child)]

Open Hawk777 opened this issue 4 years ago • 2 comments

For every struct representing an XML element, as far as I can tell, you have to write #[xml(tag = "elementname")] in front of that struct. For a field in a struct that holds a list of child elements of a certain type, as far as I can tell, you have to write #[xml(child = "elementname")] in front of the field. This appears to be double entry: the element name is specified on both the struct definition of the child element, and also on the field within the parent element. As far as I can tell, the documentation doesn’t explain under what circumstances, if any at all, these names may differ, and what it means if they do.

Hawk777 avatar Aug 26 '21 04:08 Hawk777

I have a similar feeling; I think the tag on structs is redundant for all except the top-level object (if you want to validate that the top-level tag is correct). And requiring a tag attribute for all derives is sometimes restrictive, e.g. when you have multiple elements under different tags that share the same structure.

For example, in Atom feeds, the <title>, <summary>, <content>, and <rights> tags all have the same "Text" structure. But with required tag attributes, I can't use a single struct for all of them:

#[derive(XmlRead)]
#[xml(tag = "")] // XXX: What do I put here?
pub struct Text {
    #[xml(default, attr = "type")]
    text_type: TextType,

    #[xml(text)]
    text: String,
}

So in practice, I end up duplicating this struct definition for each different tag that this structure can appear under.

So, I propose that the #[xml(tag = "...")] attribute on structs is made optional. The tags will still be well-defined whenever the struct is used as a field of another derived struct, as #[xml(child = "...")] will be required at that location.

agausmann avatar May 06 '22 20:05 agausmann

Although I think I understand the reason for having it, at least for XmlWrite, because the struct needs to know what its tag will be in order to write itself.

It might make some sense to adjust XmlWrite so that its methods accept a &str argument for the top-level tag name, which would mean that the tag attribute wouldn't be needed. And for convenience, we could keep the original XmlWrite API as a separate trait, so for types that do have a fixed tag (e.g. top level elements) you can specify the tag attribute as part of the derived impl and not have to pass it when you call the methods.

agausmann avatar May 06 '22 20:05 agausmann