diff --git a/ballerina/tests/fromXml_test.bal b/ballerina/tests/fromXml_test.bal index b37a8fc..7c870a7 100644 --- a/ballerina/tests/fromXml_test.bal +++ b/ballerina/tests/fromXml_test.bal @@ -3615,6 +3615,7 @@ isolated function testTypeRefArray() { function testXmlToRecordWithInvalidExpectedTypeForAttributes() { xml value = xml `1`; record {int[] id;}|error rec = parseAsType(value); + test:assertTrue(rec is Error); test:assertEquals((rec).message(), "attribute 'id' cannot be converted into the array type 'int[]'"); xml value2 = xml ` @@ -3628,6 +3629,7 @@ function testXmlToRecordWithInvalidExpectedTypeForAttributes() { xml value3 = xml `3`; record {record{int[] id;} b;}|error rec3 = parseAsType(value3); + test:assertTrue(rec3 is Error); test:assertEquals((rec3).message(), "attribute 'id' cannot be converted into the array type 'int[]'"); xml value4 = xml ` @@ -3636,5 +3638,30 @@ function testXmlToRecordWithInvalidExpectedTypeForAttributes() { 3 `; record {record{int[] id;}[] id;}|error rec4 = parseAsType(value4); + test:assertTrue(rec4 is Error); test:assertEquals((rec4).message(), "attribute 'id' cannot be converted into the array type 'int[]'"); + + xml value5 = xml `1`; + record {map id;}|error rec5 = parseAsType(value5); + test:assertTrue(rec5 is Error); + test:assertEquals((rec5).message(), "attribute 'id' cannot be converted into the array type 'map'"); + + xml value6 = xml `3`; + record {record{map id;} b;}|error rec6 = parseAsType(value6); + test:assertTrue(rec6 is Error); + test:assertEquals((rec6).message(), "attribute 'id' cannot be converted into the array type 'map'"); + + xml value7 = xml `1`; + record {string:RegExp id;}|error rec7 = parseAsType(value7); + test:assertTrue(rec7 is Error); + test:assertEquals((rec7).message(), "unsupported input type"); + + xml value8 = xml ` + 1 + 2 + 3 + `; + record {record{string:RegExp id;}[] id;}|error rec8 = parseAsType(value8); + test:assertTrue(rec8 is Error); + test:assertEquals((rec8).message(), "unsupported input type"); } 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 5e59ab9..47771ca 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 @@ -917,6 +917,27 @@ public static boolean isSimpleType(Type type) { }; } + public static boolean isSupportedTypeForAttributes(Type fieldType) { + if (TypeTags.isIntegerTypeTag(fieldType.getTag())) { + return true; + } + + if (TypeTags.isStringTypeTag(fieldType.getTag())) { + return true; + } + + if (TypeTags.isXMLTypeTag(fieldType.getTag())) { + return false; + } + + return switch (fieldType.getTag()) { + case TypeTags.FLOAT_TAG, TypeTags.BOOLEAN_TAG, TypeTags.NULL_TAG, + TypeTags.DECIMAL_TAG, TypeTags.BYTE_TAG, TypeTags.UNION_TAG, TypeTags.ANYDATA_TAG, + TypeTags.ANY_TAG, TypeTags.JSON_TAG -> true; + default -> false; + }; + } + /** * Holds data required for the traversing. * diff --git a/native/src/main/java/io/ballerina/lib/data/xmldata/utils/DiagnosticErrorCode.java b/native/src/main/java/io/ballerina/lib/data/xmldata/utils/DiagnosticErrorCode.java index 99f6168..ef6bf8b 100644 --- a/native/src/main/java/io/ballerina/lib/data/xmldata/utils/DiagnosticErrorCode.java +++ b/native/src/main/java/io/ballerina/lib/data/xmldata/utils/DiagnosticErrorCode.java @@ -42,8 +42,8 @@ public enum DiagnosticErrorCode { STREAM_BROKEN("XML_ERROR_015", "stream.broken"), XML_PARSE_ERROR("XML_ERROR_016", "xml.parse.error"), UNDEFINED_FIELD("XML_ERROR_0017", "undefined.field"), - ATTRIBUTE_CANNOT_CONVERT_INTO_ARRAY_TYPE("XML_ERROR_0018", - "attributes.cannot.convert.to.array.type"); + CANNOT_CONVERT_ATTRIBUTE_TO_ARRAY_TYPE("XML_ERROR_0018", + "cannot.convert.attributes.to.array.type"); String diagnosticId; String messageKey; diff --git a/native/src/main/java/io/ballerina/lib/data/xmldata/xml/XmlTraversal.java b/native/src/main/java/io/ballerina/lib/data/xmldata/xml/XmlTraversal.java index a3ce229..8e2ffcf 100644 --- a/native/src/main/java/io/ballerina/lib/data/xmldata/xml/XmlTraversal.java +++ b/native/src/main/java/io/ballerina/lib/data/xmldata/xml/XmlTraversal.java @@ -661,14 +661,20 @@ private void handleAttributes(BXmlItem xmlItem, BMap currentNod analyzerData.rootRecord); } - if (field.getFieldType().getTag() == TypeTags.ARRAY_TAG) { - throw DiagnosticLog.error(DiagnosticErrorCode.ATTRIBUTE_CANNOT_CONVERT_INTO_ARRAY_TYPE, - field.getFieldName(), field.getFieldType()); + Type fieldType = field.getFieldType(); + + if (DataUtils.isRegExpType(fieldType)) { + throw DiagnosticLog.error(DiagnosticErrorCode.UNSUPPORTED_TYPE); + } + + if (!DataUtils.isSupportedTypeForAttributes(TypeUtils.getReferredType(fieldType))) { + throw DiagnosticLog.error(DiagnosticErrorCode.CANNOT_CONVERT_ATTRIBUTE_TO_ARRAY_TYPE, + field.getFieldName(), fieldType); } try { currentNode.put(StringUtils.fromString(field.getFieldName()), - DataUtils.convertStringToExpType(attributeMap.get(key), field.getFieldType())); + DataUtils.convertStringToExpType(attributeMap.get(key), fieldType)); } catch (Exception e) { // Ignore: Expected type will mismatch when element and attribute having same name. } diff --git a/native/src/main/resources/error.properties b/native/src/main/resources/error.properties index 5dd9bc7..479f09e 100644 --- a/native/src/main/resources/error.properties +++ b/native/src/main/resources/error.properties @@ -71,5 +71,5 @@ error.xml.parse.error=\ error.undefined.field=\ undefined field ''{0}'' in record ''{1}'' -error.attributes.cannot.convert.to.array.type=\ +error.cannot.convert.attributes.to.array.type=\ attribute ''{0}'' cannot be converted into the array type ''{1}''