diff --git a/ballerina/tests/toXml_test.bal b/ballerina/tests/toXml_test.bal index 374b7348..689260cf 100644 --- a/ballerina/tests/toXml_test.bal +++ b/ballerina/tests/toXml_test.bal @@ -15,6 +15,7 @@ // under the License. import ballerina/test; +import ballerina/io; @test:Config { groups: ["toXml"] @@ -1165,36 +1166,36 @@ isolated function testRecordWithNamespaceAnnotationToXml1() returns error? { test:assertEquals(result.toString(), expected, msg = "testComplexRecordToXml result incorrect"); } -type AddressR record {| +type AddressR1 record {| string city; int code; |}; -type Wsa_ReplyTo record { +type Wsa_ReplyTo1 record { @Namespace {prefix: "wsa", uri: "example1.com"} - AddressR Address; + AddressR1 Address; }; -type Htng_ReplyTo record { - @Namespace {prefix: "htng", uri: "example2.com"} - AddressR Address; +type Htng_ReplyTo1 record { + @Namespace {prefix: "wsa", uri: "example1.com"} + AddressR1 Address; }; @Name {value: "soap"} -type Soap record { +type Soap1 record { @Name {value: "ReplyTo"} @Namespace {prefix: "wsa", uri: "example1.com"} - Wsa_ReplyTo wsaReplyTo; + Wsa_ReplyTo1 wsaReplyTo; @Name {value: "ReplyTo"} @Namespace {prefix: "htng", uri: "example2.com"} - Htng_ReplyTo htngReplyTo; + Htng_ReplyTo1 htngReplyTo; }; @test:Config { groups: ["toXml"] } isolated function testXmlToRecordWithNamespaceAttachedToFields() returns error? { - Soap val = { + Soap1 val = { htngReplyTo: { Address: { code: 40000, @@ -1213,14 +1214,71 @@ isolated function testXmlToRecordWithNamespaceAttachedToFields() returns error? string expected = "" + "" + "Kandy10000" + - "" + - "" + - "Colombo40000" + - "" + - ""; + "" + + "Colombo40000" + + ""; + io:println(xmlVal); test:assertEquals(xmlVal.toString(), expected); } +@Namespace {prefix: "wsa", uri: "example1.com"} +type AddressR2 record {| + string city; + int code; +|}; + +@Namespace {prefix: "wsa", uri: "example1.com"} +type Wsa_ReplyTo2 record { + @Namespace {prefix: "wsa", uri: "example1.com"} + AddressR2 Address; +}; + +@Namespace {prefix: "htng", uri: "example2.com"} +type Htng_ReplyTo2 record { + @Namespace {prefix: "wsa", uri: "example1.com"} + AddressR2 Address; +}; + +@Name {value: "soap"} +type Soap2 record { + @Name {value: "ReplyTo"} + @Namespace {prefix: "wsa", uri: "example1.com"} + Wsa_ReplyTo2 wsaReplyTo; + @Name {value: "ReplyTo"} + @Namespace {prefix: "htng", uri: "example2.com"} + Htng_ReplyTo2 htngReplyTo; +}; + +@test:Config { + groups: ["toXml"] +} +isolated function testXmlToRecordWithNamespaceAttachedToFieldsAndTypes() returns error? { + Soap2 val = { + htngReplyTo: { + Address: { + code: 40000, + city: "Colombo" + } + }, + wsaReplyTo: { + Address: { + code: 10000, + city: "Kandy" + } + } + }; + + xml xmlVal = check toXml(val); + string expected = "" + + "" + + "Kandy10000" + + "" + + "Colombo40000" + + ""; + io:println(xmlVal); + test:assertEquals(xmlVal.toString(), expected); +} + type RequestorID record { @Attribute string ID; diff --git a/native/src/main/java/io/ballerina/lib/data/xmldata/utils/DataUtils.java b/native/src/main/java/io/ballerina/lib/data/xmldata/utils/DataUtils.java index 1f3a4f62..95e7e277 100644 --- a/native/src/main/java/io/ballerina/lib/data/xmldata/utils/DataUtils.java +++ b/native/src/main/java/io/ballerina/lib/data/xmldata/utils/DataUtils.java @@ -460,17 +460,25 @@ private static BMap addFields(BMap input, Type } else if (fieldType.getTag() == TypeTags.TYPE_REFERENCED_TYPE_TAG) { Type referredType = TypeUtils.getReferredType(fieldType); BMap namespaceAnnotRecord = ValueCreator.createMapValue(Constants.JSON_MAP_TYPE); + boolean doesNamespaceDefinedInField = false; if (annotations.size() > 0) { String fieldName = key; key = getKeyNameFromAnnotation(annotations, key); QName qName = addFieldNamespaceAnnotation(fieldName, key, annotations, namespaceAnnotRecord); + if (!qName.getNamespaceURI().equals("")) { + doesNamespaceDefinedInField = true; + } String localPart = qName.getLocalPart(); key = qName.getPrefix().isBlank() ? localPart : qName.getPrefix() + ":" + localPart; } - BMap subRecordAnnotations = ((RecordType) referredType).getAnnotations(); - key = getElementName(subRecordAnnotations, key); + BMap annotationRecord = ValueCreator.createMapValue(Constants.JSON_MAP_TYPE); - processSubRecordAnnotation(subRecordAnnotations, annotationRecord); + if (!doesNamespaceDefinedInField) { + BMap subRecordAnnotations = ((RecordType) referredType).getAnnotations(); + key = getElementName(subRecordAnnotations, key); + processSubRecordAnnotation(subRecordAnnotations, annotationRecord); + } + BMap subRecordValue = addFields(((BMap) value), referredType); addNamespaceToSubRecord(key, namespaceAnnotRecord, subRecordValue); if (annotationRecord.size() > 0) { @@ -744,6 +752,9 @@ private static String getElementName(BMap annotation, String ke key = prefix.getValue().concat(Constants.COLON).concat(key); } } + } + + for (BString value : keys) { if (value.getValue().endsWith(Constants.NAME)) { key = processNameAnnotation(annotation, key, value, hasNamespaceAnnotation); }