diff --git a/smithy-aws-protocol-tests/model/restXml/document-unions.smithy b/smithy-aws-protocol-tests/model/restXml/document-unions.smithy
new file mode 100644
index 00000000000..14811a70b77
--- /dev/null
+++ b/smithy-aws-protocol-tests/model/restXml/document-unions.smithy
@@ -0,0 +1,278 @@
+// This file defines test cases that serialize synthesized XML documents
+// in the payload of HTTP requests and responses.
+
+$version: "1.0"
+
+namespace aws.protocoltests.restxml
+
+use aws.protocols#restXml
+use smithy.test#httpRequestTests
+use smithy.test#httpResponseTests
+
+// This example serializes simple scalar types in the top level XML document.
+// Note that headers are not serialized in the payload.
+@idempotent
+@http(uri: "/XmlUnions", method: "PUT")
+operation XmlUnions {
+ input: XmlUnionsInputOutput,
+ output: XmlUnionsInputOutput
+}
+
+apply XmlUnions @httpRequestTests([
+ {
+ id: "XmlUnionsWithStructMember",
+ documentation: "Serializes union struct member",
+ protocol: restXml,
+ method: "PUT",
+ uri: "/XmlUnions",
+ body: """
+
+
+
+ string
+ true
+ 1
+ 2
+ 3
+ 4
+ 5.5
+ 6.5
+
+
+
+ """,
+ bodyMediaType: "application/xml",
+ headers: {
+ "Content-Type": "application/xml",
+ },
+ params: {
+ unionValue: {
+ structValue: {
+ stringValue: "string",
+ booleanValue: true,
+ byteValue: 1,
+ shortValue: 2,
+ integerValue: 3,
+ longValue: 4,
+ floatValue: 5.5,
+ doubleValue: 6.5,
+ },
+ },
+ }
+ },
+ {
+ id: "XmlUnionsWithStringMember",
+ documentation: "serialize union string member",
+ protocol: restXml,
+ method: "PUT",
+ uri: "/XmlUnions",
+ body: """
+
+
+ some string
+
+
+ """,
+ bodyMediaType: "application/xml",
+ headers: {
+ "Content-Type": "application/xml",
+ },
+ params: {
+ unionValue: {
+ stringValue: "some string",
+ },
+ }
+ },
+ {
+ id: "XmlUnionsWithBooleanMember",
+ documentation: "Serializes union boolean member",
+ protocol: restXml,
+ method: "PUT",
+ uri: "/XmlUnions",
+ body: """
+
+
+ true
+
+
+ """,
+ bodyMediaType: "application/xml",
+ headers: {
+ "Content-Type": "application/xml",
+ },
+ params: {
+ unionValue: {
+ booleanValue: true,
+ },
+ }
+ },
+ {
+ id: "XmlUnionsWithUnionMember",
+ documentation: "Serializes union union member",
+ protocol: restXml,
+ method: "PUT",
+ uri: "/XmlUnions",
+ body: """
+
+
+
+ true
+
+
+
+ """,
+ bodyMediaType: "application/xml",
+ headers: {
+ "Content-Type": "application/xml",
+ },
+ params: {
+ unionValue: {
+ unionValue: {
+ booleanValue: true,
+ },
+ },
+ }
+ },
+])
+
+apply XmlUnions @httpResponseTests([
+ {
+ id: "XmlUnionsWithStructMember",
+ documentation: "Serializes union struct member",
+ protocol: restXml,
+ code: 200,
+ body: """
+
+
+
+ string
+ true
+ 1
+ 2
+ 3
+ 4
+ 5.5
+ 6.5
+
+
+
+ """,
+ bodyMediaType: "application/xml",
+ headers: {
+ "Content-Type": "application/xml",
+ },
+ params: {
+ unionValue: {
+ structValue: {
+ stringValue: "string",
+ booleanValue: true,
+ byteValue: 1,
+ shortValue: 2,
+ integerValue: 3,
+ longValue: 4,
+ floatValue: 5.5,
+ doubleValue: 6.5,
+ },
+ },
+ }
+ },
+ {
+ id: "XmlUnionsWithStringMember",
+ documentation: "Serializes union string member",
+ protocol: restXml,
+ code: 200,
+ body: """
+
+
+ some string
+
+
+ """,
+ bodyMediaType: "application/xml",
+ headers: {
+ "Content-Type": "application/xml",
+ },
+ params: {
+ unionValue: {
+ stringValue: "some string",
+ },
+ }
+ },
+ {
+ id: "XmlUnionsWithBooleanMember",
+ documentation: "Serializes union boolean member",
+ protocol: restXml,
+ code: 200,
+ body: """
+
+
+ true
+
+
+ """,
+ bodyMediaType: "application/xml",
+ headers: {
+ "Content-Type": "application/xml",
+ },
+ params: {
+ unionValue: {
+ booleanValue: true,
+ },
+ }
+ },
+ {
+ id: "XmlUnionsWithUnionMember",
+ documentation: "Serializes union union member",
+ protocol: restXml,
+ code: 200,
+ body: """
+
+
+
+ true
+
+
+
+ """,
+ bodyMediaType: "application/xml",
+ headers: {
+ "Content-Type": "application/xml",
+ },
+ params: {
+ unionValue: {
+ unionValue: {
+ booleanValue: true,
+ },
+ },
+ }
+ },
+])
+
+structure XmlUnionsInputOutput {
+ unionValue: XmlUnionShape,
+}
+
+union XmlUnionShape {
+ stringValue: String,
+ booleanValue: Boolean,
+ byteValue: Byte,
+ shortValue: Short,
+ integerValue: Integer,
+ longValue: Long,
+ floatValue: Float,
+ doubleValue: Double,
+
+ unionValue: XmlUnionShape,
+ structValue: XmlNestedUnionStruct,
+}
+
+structure XmlNestedUnionStruct {
+ stringValue: String,
+ booleanValue: Boolean,
+ byteValue: Byte,
+ shortValue: Short,
+ integerValue: Integer,
+ longValue: Long,
+ floatValue: Float,
+ doubleValue: Double,
+}
diff --git a/smithy-aws-protocol-tests/model/restXml/main.smithy b/smithy-aws-protocol-tests/model/restXml/main.smithy
index 1829415ce69..11a03075349 100644
--- a/smithy-aws-protocol-tests/model/restXml/main.smithy
+++ b/smithy-aws-protocol-tests/model/restXml/main.smithy
@@ -62,6 +62,7 @@ service RestXml {
// Synthesized XML document body tests
SimpleScalarProperties,
+ XmlUnions,
XmlBlobs,
XmlTimestamps,
XmlEnums,