diff --git a/src/Api/Serializer/RestXmlSerializer.php b/src/Api/Serializer/RestXmlSerializer.php index 16d8ae7b96..2cf496a4b9 100644 --- a/src/Api/Serializer/RestXmlSerializer.php +++ b/src/Api/Serializer/RestXmlSerializer.php @@ -41,7 +41,7 @@ protected function payload(StructureShape $member, array $value, array &$opts) */ private function getXmlBody(StructureShape $member, array $value) { - $xmlBody = (string)$this->xmlBody->build($member, $value); + $xmlBody = $this->xmlBody->build($member, $value); $xmlBody = str_replace("'", "'", $xmlBody); $xmlBody = str_replace('\r', " ", $xmlBody); $xmlBody = str_replace('\n', " ", $xmlBody); diff --git a/src/Api/Serializer/XmlBody.php b/src/Api/Serializer/XmlBody.php index 9ce967e2e1..28393bbf2b 100644 --- a/src/Api/Serializer/XmlBody.php +++ b/src/Api/Serializer/XmlBody.php @@ -99,10 +99,8 @@ private function add_structure( // Default to member name $elementName = $k; - // Only use locationName for non-structure members - if (!($definition['member'] instanceof StructureShape) - && $definition['member']['locationName'] - ) { + if ($definition['member']['locationName'] + && !isset($definition['member']['locationNameAtStructureLevel'])) { $elementName = $definition['member']['locationName']; } diff --git a/src/Api/ShapeMap.php b/src/Api/ShapeMap.php index 269b2d3a06..1593c2e321 100644 --- a/src/Api/ShapeMap.php +++ b/src/Api/ShapeMap.php @@ -51,7 +51,14 @@ public function resolve(array $shapeRef) return $this->simple[$shape]; } - $definition = $shapeRef + $this->definitions[$shape]; + $shapeDefinition = $this->definitions[$shape]; + $definition = $shapeRef + $shapeDefinition; + // Property to know whether the locationName was set at member level + // or the structure level. + if (isset($shapeDefinition['locationName'])) { + $definition['locationNameAtStructureLevel'] = true; + } + $definition['name'] = $definition['shape']; if (isset($definition['shape'])) { unset($definition['shape']); diff --git a/tests/Api/test_cases/protocols/input/rest-xml.json b/tests/Api/test_cases/protocols/input/rest-xml.json index d0e8ed577a..6295fd7411 100644 --- a/tests/Api/test_cases/protocols/input/rest-xml.json +++ b/tests/Api/test_cases/protocols/input/rest-xml.json @@ -541,6 +541,84 @@ } ] }, + { + "description": "Test cases for xmlName at member level operation", + "metadata": { + "apiVersion": "2019-12-16", + "auth": [ + "aws.auth#sigv4" + ], + "endpointPrefix": "restxml", + "protocol": "rest-xml", + "protocols": [ + "rest-xml" + ], + "serviceFullName": "RestXml", + "serviceId": "Rest Xml Protocol", + "signatureVersion": "v4", + "signingName": "RestXml", + "uid": "rest-xml-protocol-2019-12-16" + }, + "shapes": { + "MyShapeInputAndOutput": { + "type": "structure", + "members": { + "nested": { + "shape": "Payload", + "locationName": "CustomPayload" + } + }, + "locationName": "MyShape" + }, + "Payload": { + "type": "structure", + "members": { + "name": { + "shape": "String" + } + } + }, + "String": { + "type": "string" + } + }, + "cases": [ + { + "id": "XMLNameAtMemberLevel", + "given": { + "name": "XMLNameAtMemberLevel", + "http": { + "method": "PUT", + "requestUri": "/XMLNameAtMemberLevel", + "responseCode": 200 + }, + "input": { + "shape": "MyShapeInputAndOutput", + "locationName": "XMLNameAtMemberLevelRequest" + }, + "documentation": "

The following example serializes a body that uses an XML name, changing the wrapper name.

", + "idempotent": true + }, + "description": "Serializes a payload using a wrapper name based on the xmlName", + "params": { + "nested": { + "name": "TestParameterValue" + } + }, + "serialized": { + "method": "PUT", + "uri": "/XMLNameAtMemberLevel", + "body": "TestParameterValue", + "headers": { + "Content-Type": "application/xml" + }, + "requireHeaders": [ + "Content-Length" + ] + } + } + ] + }, { "description": "Test cases for ConstantAndVariableQueryString operation", "metadata": {