diff --git a/.changes/next-release/feature-5dc78e390fc8e0ba147cdd1d2ab8b84f1d6ce22a.json b/.changes/next-release/feature-5dc78e390fc8e0ba147cdd1d2ab8b84f1d6ce22a.json new file mode 100644 index 00000000000..5772460cdbe --- /dev/null +++ b/.changes/next-release/feature-5dc78e390fc8e0ba147cdd1d2ab8b84f1d6ce22a.json @@ -0,0 +1,7 @@ +{ + "type": "feature", + "description": "Added protocol test to test xml attribute members that are declared between non-attribute members.", + "pull_requests": [ + "[#2870](https://github.com/smithy-lang/smithy/pull/2870)" + ] +} diff --git a/smithy-aws-protocol-tests/model/restXml/document-xml-attributes.smithy b/smithy-aws-protocol-tests/model/restXml/document-xml-attributes.smithy index 1b5177de307..28b322039cd 100644 --- a/smithy-aws-protocol-tests/model/restXml/document-xml-attributes.smithy +++ b/smithy-aws-protocol-tests/model/restXml/document-xml-attributes.smithy @@ -158,3 +158,87 @@ apply XmlAttributesOnPayload @httpResponseTests([ structure XmlAttributesPayloadRequest with [XmlAttributesInputOutput] {} structure XmlAttributesPayloadResponse with [XmlAttributesInputOutput] {} + +/// This example serializes an XML attribute on a payload when it's defined in the middle of the member list. +/// This tests that implementations correctly write attributes immediately after the element start tag, +/// which is critical for languages like C# where attribute writing must happen before child elements. +@idempotent +@http(uri: "/XmlAttributesInMiddle", method: "PUT") +operation XmlAttributesInMiddle { + input := { + @httpPayload + payload: XmlAttributesInMiddlePayloadRequest + } + output := { + @httpPayload + payload: XmlAttributesInMiddlePayloadResponse + } +} + +apply XmlAttributesInMiddle @httpRequestTests([ + { + id: "XmlAttributesInMiddle", + documentation: "Serializes XML attributes on a payload when the xmlAttribute trait targets a member in the middle of the member list", + protocol: restXml, + method: "PUT", + uri: "/XmlAttributesInMiddle", + body: """ + + Foo + Baz + + """, + bodyMediaType: "application/xml", + headers: { + "Content-Type": "application/xml" + }, + params: { + payload: { + foo: "Foo", + attr: "attributeValue", + baz: "Baz" + } + } + } +]) + +apply XmlAttributesInMiddle @httpResponseTests([ + { + id: "XmlAttributesInMiddle", + documentation: "Deserializes XML attributes on a payload when the xmlAttribute trait targets a member in the middle of the member list", + protocol: restXml, + code: 200, + body: """ + + Foo + Baz + + """, + bodyMediaType: "application/xml", + headers: { + "Content-Type": "application/xml" + }, + params: { + payload: { + foo: "Foo", + attr: "attributeValue", + baz: "Baz" + } + } + } +]) + +@mixin +structure XmlAttributesMiddleMemberInputOutput { + foo: String, + + @xmlAttribute + @xmlName("test") + attr: String, + + baz: String, +} + +structure XmlAttributesInMiddlePayloadRequest with [XmlAttributesMiddleMemberInputOutput] {} + +structure XmlAttributesInMiddlePayloadResponse with [XmlAttributesMiddleMemberInputOutput] {} diff --git a/smithy-aws-protocol-tests/model/restXml/main.smithy b/smithy-aws-protocol-tests/model/restXml/main.smithy index 75380f4a8c3..bf2e764a175 100644 --- a/smithy-aws-protocol-tests/model/restXml/main.smithy +++ b/smithy-aws-protocol-tests/model/restXml/main.smithy @@ -93,6 +93,7 @@ service RestXml { // @xmlAttribute tests XmlAttributes, XmlAttributesOnPayload, + XmlAttributesInMiddle, // @xmlNamespace trait tests XmlNamespaces,