Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conflict with multiple elements with the same name but different prefixes #186

Open
mtorromeo opened this issue May 29, 2024 · 7 comments
Open

Comments

@mtorromeo
Copy link

mtorromeo commented May 29, 2024

Hi,
I'm trying to deserialize an XML which have multiple elements with the same name but defined in different namespaces and consequently using different prefixes.

The actual XSDs are rather complex, but the problem can be illustrated with this snippet:

<error>
  <reasonCode>1</reasonCode>
  <ext:reasonCode>1234</ext:reasonCode>
</error>

which I tried implementing with this struct:

pub struct ErrorType {
    #[yaserde(rename = "reasonCode", prefix = "myns")]
    pub reason_code: Option<u16>,
    #[yaserde(rename = "reasonCode", prefix = "ext")]
    pub ext_reason_code: Option<u16>,
}

but this results in the following error:

error[E0428]: the name `__Visitor_ReasonCode_` is defined multiple times

Is this supported?

@mtorromeo
Copy link
Author

I got past this error with the following patch:

--- a/yaserde_derive/src/common/field.rs
+++ b/yaserde_derive/src/common/field.rs
@@ -90,6 +90,13 @@ impl YaSerdeField {
       },
     );
 
+    let prefix = self
+      .attributes
+      .prefix
+      .clone()
+      .map(|p| format!("{}_", p.to_upper_camel_case()))
+      .unwrap_or_default();
+
     let attribute = self
       .attributes
       .attribute
@@ -98,7 +105,8 @@ impl YaSerdeField {
 
     Ident::new(
       &format!(
-        "__Visitor_{attribute}{}_{}",
+        "__Visitor_{attribute}{}{}_{}",
+        prefix,
         label.replace('.', "_").to_upper_camel_case(),
         struct_id
       ),

But then I get a new error at runtime when trying to deserialize an element <ext:reasonCode>:

bad namespace for reasonCode, found http://example.com/ext

It seems like yaserde reads the "reasonCode" name and expects it to use the namespace of "myns" instead of considering the "ext" prefix?

@mtorromeo
Copy link
Author

By looking at the expanded macro the issue is in the match statement on the name which is generated with 2 itentical branches:

                                match name.local_name.as_str() {
                                    "reasonCode" => {
                                        // ...
                                    }
                                    "reasonCode" => {
                                        // ...
                                    }
                                }

so it will always only use the first definition

@mtorromeo
Copy link
Author

@MarcAntoine-Arnaud sorry to ping you, but is there any chance that you could take a look at this?

@MarcAntoine-Arnaud
Copy link
Contributor

Hi @mtorromeo ,

Sorry for the delay.
Thank you for your analysis, it was the good way, just missing to complete the match with namespace.

I have implemented it in a067b85
and released in yaserde v0.11.

Please close the issue if it's complete once you've validated.

@mtorromeo
Copy link
Author

Just wanted to let you know that I plan to get back to you with my feedback as soon as I can test it, but it'll probably take a week or two.

In the meantime, thank you for your work!

@mtorromeo
Copy link
Author

Hi, I did some tests. The specific issue with homonymous elements is fixed, but I am having some other problems using mixed namespaces.

I think it's issue #177

@mtorromeo
Copy link
Author

I think the same issue is still present for enum variants.

To use the same example used previously, this enum does not work properly:

    pub enum ErrorCodeType {
        #[yaserde(rename = "reasonCode", prefix = "myns")]
        ReasonCode(u16),

        #[yaserde(rename = "reasonCode", prefix = "ext")]
        StrReasonCode(String),

        #[default]
        #[allow(non_camel_case_types)]
        __undefined__,
    }

@mtorromeo mtorromeo reopened this Sep 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants