From ba93e9bb4f7b7a476ea89e7ad383af83b892200d Mon Sep 17 00:00:00 2001 From: Sasindu Alahakoon Date: Mon, 18 Nov 2024 11:56:59 +0530 Subject: [PATCH] Add tests for validate and fromJson APIs --- ballerina/tests/test_from_json.bal | 26 ++++++++++ .../tests/xsd_choice_test_with_parse_type.bal | 18 +++++++ .../xsd_sequence_tests_with_parse_type.bal | 33 ++++++++++++ .../xsd_validation_with_file_path_tests.bal | 45 +++++++++------- ballerina/xml_api.bal | 8 +-- .../xmldata/utils/DiagnosticErrorCode.java | 3 +- .../lib/data/xmldata/xml/Native.java | 2 +- .../lib/data/xmldata/xml/XSDValidator.java | 52 +++++++++++++------ native/src/main/resources/error.properties | 3 ++ 9 files changed, 149 insertions(+), 41 deletions(-) create mode 100644 ballerina/tests/test_from_json.bal diff --git a/ballerina/tests/test_from_json.bal b/ballerina/tests/test_from_json.bal new file mode 100644 index 0000000..fdf5588 --- /dev/null +++ b/ballerina/tests/test_from_json.bal @@ -0,0 +1,26 @@ +import ballerina/test; + +@test:Config {groups: ["xsd", "to_xml"], dataProvider: fromJsonDataProvider} +function testFromJson(json value, xml expected) returns error?{ + xml|Error xmlResult = fromJson(value); + test:assertEquals(xmlResult, expected); +} + +function fromJsonDataProvider() returns [json, xml][] { + return [ + [{a: {b: 2, c: 3}}, xml `23`], + [{a: {a: 1}}, xml `1`], + [{a: {d: 4, e: {f: 5, g: "text"}}}, xml `45text`], + [{root: {nested: {value1: "example", value2: 10}}}, xml `example10`], + [{book: {title: "XML Guide", author: "John Doe", year: 2024}}, xml `XML GuideJohn Doe2024`], + [{library: {section: {book1: "Book A", book2: "Book B"}}}, xml `
Book ABook B
`], + [{person: {name: "Alice", details: {age: 30, city: "Wonderland"}}}, xml `Alice
30Wonderland
`], + [{catalog: {item: [{id: 1, name: "Item 1"}, {id: 2, name: "Item 2"}]}}, xml `1Item 12Item 2`], + [{company: {employee: {id: 1001, name: "Bob", department: "Engineering"}}}, xml `1001BobEngineering`], + [{'order: {orderId: 5001, items: {item1: "Widget", item2: "Gadget"}}}, xml `5001WidgetGadget`], + [{menu: {dish: [{name: "Pasta", price: 12.5}, {name: "Salad", price: 8.0}]}}, xml `Pasta12.5Salad8.0`], + [{report: {entries: [{date: "2024-10-01", detail: "Entry 1"}, {date: "2024-10-02", detail: "Entry 2"}]}}, xml `2024-10-01Entry 12024-10-02Entry 2`], + [{shoppingList: {items: [{item: "Apples", quantity: 5}, {item: "Bananas", quantity: 3}]}}, xml `Apples5Bananas3`], + [{conference: {session: [{topic: "AI Trends", speaker: "Dr. Smith"}, {topic: "Web 3.0", speaker: "Jane Doe"}]}}, xml `AI TrendsDr. SmithWeb 3.0Jane Doe`] + ]; +} diff --git a/ballerina/tests/xsd_choice_test_with_parse_type.bal b/ballerina/tests/xsd_choice_test_with_parse_type.bal index 6892620..1d66f68 100644 --- a/ballerina/tests/xsd_choice_test_with_parse_type.bal +++ b/ballerina/tests/xsd_choice_test_with_parse_type.bal @@ -41,26 +41,36 @@ function testXsdChoiceWithXmlValue() returns error? { v = parseAsType(xmlValue); test:assertEquals(v, {choice_XSDChoiceWithXmlValueRecord: {age: 10}}); test:assertEquals(toXml(check v), xmlValue); + Error? e = validate(XSDChoiceWithXmlValueRecord, xmlValue); + test:assertEquals(e, ()); xmlValue = xml `10.5`; v = parseAsType(xmlValue); test:assertEquals(v, {choice_XSDChoiceWithXmlValueRecord: {salary: 10.5}}); test:assertEquals(toXml(check v), xmlValue); + e = validate(XSDChoiceWithXmlValueRecord, xmlValue); + test:assertEquals(e, ()); xmlValue = xml `1011.1`; v = parseAsType(xmlValue); test:assertTrue(v is Error); test:assertEquals((v).message(), "'choice_XSDChoiceWithXmlValueRecord' occurs more than the max allowed times"); + e = validate(XSDChoiceWithXmlValueRecord, xmlValue); + test:assertEquals((e).message(), "Invalid XML found: ''choice_XSDChoiceWithXmlValueRecord' occurs more than the max allowed times'"); xmlValue = xml `11.111.1`; v = parseAsType(xmlValue); test:assertTrue(v is Error); test:assertEquals((v).message(), "'choice_XSDChoiceWithXmlValueRecord' occurs more than the max allowed times"); + e = validate(XSDChoiceWithXmlValueRecord, xmlValue); + test:assertEquals((e).message(), "Invalid XML found: ''choice_XSDChoiceWithXmlValueRecord' occurs more than the max allowed times'"); xmlValue = xml ``; v = parseAsType(xmlValue); test:assertTrue(v is Error); test:assertEquals((v).message(), "'choice_XSDChoiceWithXmlValueRecord' occurs less than the min required times"); + e = validate(XSDChoiceWithXmlValueRecord, xmlValue); + test:assertEquals((e).message(), "Invalid XML found: ''choice_XSDChoiceWithXmlValueRecord' occurs less than the min required times'"); } @Name { @@ -585,19 +595,27 @@ function testXsdChoiceWithXmlValue10() returns error? { XSDChoiceWithXmlValueRecord10|Error v2 = parseAsType(xmlValue); test:assertEquals(v2, {choice_XSDChoiceWithXmlValueRecord10_1: {field1: {value1: {a: "1"}}}, choice_XSDChoiceWithXmlValueRecord10_2: {field5: {value2: {"d": "2"}}}}); test:assertEquals(toXml(check v2), xmlValue); + Error? e = validate(XSDChoiceWithXmlValueRecord10, xmlValue); + test:assertEquals(e, ()); xmlValue = xml `112`; v2 = parseAsType(xmlValue); test:assertTrue(v2 is Error); test:assertEquals((v2).message(), "'choice_XSDChoiceWithXmlValueRecord10_1' occurs more than the max allowed times"); + e = validate(XSDChoiceWithXmlValueRecord10, xmlValue); + test:assertEquals((e).message(), "Invalid XML found: ''choice_XSDChoiceWithXmlValueRecord10_1' occurs more than the max allowed times'"); xmlValue = xml `122`; v2 = parseAsType(xmlValue); test:assertTrue(v2 is Error); test:assertEquals((v2).message(), "'choice_XSDChoiceWithXmlValueRecord10_2' occurs more than the max allowed times"); + e = validate(XSDChoiceWithXmlValueRecord10, xmlValue); + test:assertEquals((e).message(), "Invalid XML found: ''choice_XSDChoiceWithXmlValueRecord10_2' occurs more than the max allowed times'"); xmlValue = xml `112`; v2 = parseAsType(xmlValue); test:assertTrue(v2 is Error); test:assertEquals((v2).message(), "'value2' occurs more than the max allowed times"); + e = validate(XSDChoiceWithXmlValueRecord10, xmlValue); + test:assertEquals((e).message(), "Invalid XML found: ''value2' occurs more than the max allowed times'"); } diff --git a/ballerina/tests/xsd_sequence_tests_with_parse_type.bal b/ballerina/tests/xsd_sequence_tests_with_parse_type.bal index 1586da4..e84728a 100644 --- a/ballerina/tests/xsd_sequence_tests_with_parse_type.bal +++ b/ballerina/tests/xsd_sequence_tests_with_parse_type.bal @@ -47,26 +47,40 @@ function testXsdSequenceWithXmlValue() returns error? { test:assertEquals((check v).seq_XSDSequenceRecordWithXmlValue.age, 13); test:assertEquals((check v).seq_XSDSequenceRecordWithXmlValue.salary, 11.1); test:assertEquals(toXml(check v), xmlValue); + Error? e = validate(XSDSequenceRecordWithXmlValue, xmlValue); + test:assertTrue(e is ()); xmlValue = xml `11.1`; v = parseAsType(xmlValue); test:assertTrue(v is Error); test:assertEquals((v).message(), "Element 'salary' is not in the correct order in 'seq_XSDSequenceRecordWithXmlValue'"); + e = validate(XSDSequenceRecordWithXmlValue, xmlValue); + test:assertTrue(e is Error); + test:assertEquals(( e).message(), "Invalid XML found: 'Element 'salary' is not in the correct order in 'seq_XSDSequenceRecordWithXmlValue''"); xmlValue = xml `13`; v = parseAsType(xmlValue); test:assertTrue(v is Error); test:assertEquals((v).message(), "Element(s) 'salary' is not found in 'seq_XSDSequenceRecordWithXmlValue'"); + e = validate(XSDSequenceRecordWithXmlValue, xmlValue); + test:assertTrue(e is Error); + test:assertEquals(( e).message(), "Invalid XML found: 'Element(s) 'salary' is not found in 'seq_XSDSequenceRecordWithXmlValue''"); xmlValue = xml ``; v = parseAsType(xmlValue); test:assertTrue(v is Error); test:assertEquals((v).message(), ("required field 'seq_XSDSequenceRecordWithXmlValue' not present in XML"), msg = (v).message()); + e = validate(XSDSequenceRecordWithXmlValue, xmlValue); + test:assertTrue(e is Error); + test:assertEquals(( e).message(), "Invalid XML found: 'required field 'seq_XSDSequenceRecordWithXmlValue' not present in XML'"); xmlValue = xml `11.113`; v = parseAsType(xmlValue); test:assertTrue(v is Error); test:assertEquals((v).message(), "Element 'salary' is not in the correct order in 'seq_XSDSequenceRecordWithXmlValue'"); + e = validate(XSDSequenceRecordWithXmlValue, xmlValue); + test:assertTrue(e is Error); + test:assertEquals(( e).message(), "Invalid XML found: 'Element 'salary' is not in the correct order in 'seq_XSDSequenceRecordWithXmlValue''"); } @Name { @@ -979,34 +993,53 @@ function testXsdSequenceWithXmlValue13() returns error? { XSDSequenceRecordWithXmlValue13|Error v2 = parseAsType(xmlValue); test:assertEquals(v2, {seq_XSDSequenceRecordWithXmlValue13_1: {field1: {value1: {a: "1", b: "2", c: "3"}}, field2: {value2: {d: "1", e: "2", f: "3"}}, field3: {value3: {g: "1", h: "2", i: "3"}}}, seq_XSDSequenceRecordWithXmlValue13_2: {field4: {value1: {a: "1", b: "2", c: "3"}}, field5: {value2: {d: "1", e: "2", f: "3"}}, field6: {value3: {g: "1", h: "2", i: "3"}}}}); test:assertEquals(toXml(check v2), xml `123123123123123123`); + Error? e = validate(XSDSequenceRecordWithXmlValue13, xmlValue); + test:assertTrue(e is ()); xmlValue = xml `123123123`; v2 = parseAsType(xmlValue); test:assertEquals(v2, {seq_XSDSequenceRecordWithXmlValue13_2: {field4: {value1: {a: "1", b: "2", c: "3"}}, field5: {value2: {d: "1", e: "2", f: "3"}}, field6: {value3: {g: "1", h: "2", i: "3"}}}}); test:assertEquals(toXml(check v2), xml `123123123`); + e = validate(XSDSequenceRecordWithXmlValue13, xmlValue); + test:assertTrue(e is ()); xmlValue = xml `123123123123123123123`; v2 = parseAsType(xmlValue); test:assertTrue(v2 is Error); test:assertEquals((v2).message(), "Element(s) 'field6' is not found in 'seq_XSDSequenceRecordWithXmlValue13_2'"); + e = validate(XSDSequenceRecordWithXmlValue13, xmlValue); + test:assertTrue(e is Error); + test:assertEquals((e).message(), "Invalid XML found: 'Element(s) 'field6' is not found in 'seq_XSDSequenceRecordWithXmlValue13_2''"); xmlValue = xml `123123123123121233123`; v2 = parseAsType(xmlValue); test:assertTrue(v2 is Error); test:assertEquals((v2).message(), "Element(s) 'f' is not found in 'value2'"); + e = validate(XSDSequenceRecordWithXmlValue13, xmlValue); + test:assertTrue(e is Error); + test:assertEquals((e).message(), "Invalid XML found: 'Element(s) 'f' is not found in 'value2''"); xmlValue = xml `123123123123123132`; v2 = parseAsType(xmlValue); test:assertTrue(v2 is Error); test:assertEquals((v2).message(), "Element 'i' is not in the correct order in 'value3'"); + e = validate(XSDSequenceRecordWithXmlValue13, xmlValue); + test:assertTrue(e is Error); + test:assertEquals((e).message(), "Invalid XML found: 'Element 'i' is not in the correct order in 'value3''"); xmlValue = xml `132123123123123123`; v2 = parseAsType(xmlValue); test:assertTrue(v2 is Error); test:assertEquals((v2).message(), "Element 'c' is not in the correct order in 'value1'"); + e = validate(XSDSequenceRecordWithXmlValue13, xmlValue); + test:assertTrue(e is Error); + test:assertEquals((e).message(), "Invalid XML found: 'Element 'c' is not in the correct order in 'value1''"); xmlValue = xml `123123123123123123`; v2 = parseAsType(xmlValue); test:assertTrue(v2 is Error); test:assertEquals((v2).message(), ("Element 'field5' is not in the correct order in 'seq_XSDSequenceRecordWithXmlValue13_2'"), msg = (v2).message()); + e = validate(XSDSequenceRecordWithXmlValue13, xmlValue); + test:assertTrue(e is Error); + test:assertEquals((e).message(), "Invalid XML found: 'Element 'field5' is not in the correct order in 'seq_XSDSequenceRecordWithXmlValue13_2''"); } diff --git a/ballerina/tests/xsd_validation_with_file_path_tests.bal b/ballerina/tests/xsd_validation_with_file_path_tests.bal index 83f39c6..e6e666c 100644 --- a/ballerina/tests/xsd_validation_with_file_path_tests.bal +++ b/ballerina/tests/xsd_validation_with_file_path_tests.bal @@ -30,11 +30,12 @@ function testValidateSchema1() returns error? { xml validXml = check readXmlFile(validXmlPath); xml invalidXml = check readXmlFile(invalidXmlPath); - boolean isValid = validate(xsdPath, validXml); - test:assertTrue(isValid, msg = "Valid XML should pass validation"); + Error? e = validate(xsdPath, validXml); + test:assertTrue(e is (), msg = "Valid XML should pass validation"); - boolean isInvalid = validate(xsdPath, invalidXml); - test:assertFalse(isInvalid, msg = "Invalid XML should fail validation"); + e = validate(xsdPath, invalidXml); + test:assertTrue(e is Error, msg = "Invalid XML should fail validation"); + test:assertTrue((e).message().includes("Invalid XML found"), msg = "Invalid XML should fail validation"); } @test:Config {groups: ["xsd"]} @@ -46,11 +47,12 @@ function testValidateSchema2() returns error? { xml validXml = check readXmlFile(validXmlPath); xml invalidXml = check readXmlFile(invalidXmlPath); - boolean isValid = validate(xsdPath, validXml); - test:assertTrue(isValid, msg = "Valid XML should pass validation"); + Error? e = validate(xsdPath, validXml); + test:assertTrue(e is (), msg = "Valid XML should pass validation"); - boolean isInvalid = validate(xsdPath, invalidXml); - test:assertFalse(isInvalid, msg = "Invalid XML should fail validation"); + e = validate(xsdPath, invalidXml); + test:assertTrue(e is Error, msg = "Invalid XML should fail validation"); + test:assertTrue((e).message().includes("Invalid XML found"), msg = "Invalid XML should fail validation"); } @test:Config {groups: ["xsd"]} @@ -62,11 +64,12 @@ function testValidateSchema3() returns error? { xml validXml = check readXmlFile(validXmlPath); xml invalidXml = check readXmlFile(invalidXmlPath); - boolean isValid = validate(xsdPath, validXml); - test:assertTrue(isValid, msg = "Valid XML should pass validation"); + Error? e = validate(xsdPath, validXml); + test:assertTrue(e is (), msg = "Valid XML should pass validation"); - boolean isInvalid = validate(xsdPath, invalidXml); - test:assertFalse(isInvalid, msg = "Invalid XML should fail validation"); + e = validate(xsdPath, invalidXml); + test:assertTrue(e is Error, msg = "Invalid XML should fail validation"); + test:assertTrue((e).message().includes("Invalid XML found"), msg = "Invalid XML should fail validation"); } @test:Config {groups: ["xsd"]} @@ -78,11 +81,12 @@ function testValidateSchema4() returns error? { xml validXml = check readXmlFile(validXmlPath); xml invalidXml = check readXmlFile(invalidXmlPath); - boolean isValid = validate(xsdPath, validXml); - test:assertTrue(isValid, msg = "Valid XML should pass validation"); + Error? e = validate(xsdPath, validXml); + test:assertTrue(e is (), msg = "Valid XML should pass validation"); - boolean isInvalid = validate(xsdPath, invalidXml); - test:assertFalse(isInvalid, msg = "Invalid XML should fail validation"); + e = validate(xsdPath, invalidXml); + test:assertTrue(e is Error, msg = "Invalid XML should fail validation"); + test:assertTrue((e).message().includes("Invalid XML found"), msg = "Invalid XML should fail validation"); } @test:Config {groups: ["xsd"]} @@ -94,9 +98,10 @@ function testValidateSchema5() returns error? { xml validXml = check readXmlFile(validXmlPath); xml invalidXml = check readXmlFile(invalidXmlPath); - boolean isValid = validate(xsdPath, validXml); - test:assertTrue(isValid, msg = "Valid XML should pass validation"); + Error? e = validate(xsdPath, validXml); + test:assertTrue(e is (), msg = "Valid XML should pass validation"); - boolean isInvalid = validate(xsdPath, invalidXml); - test:assertFalse(isInvalid, msg = "Invalid XML should fail validation"); + e = validate(xsdPath, invalidXml); + test:assertTrue(e is Error, msg = "Invalid XML should fail validation"); + test:assertTrue((e).message().includes("Invalid XML found"), msg = "Invalid XML should fail validation"); } diff --git a/ballerina/xml_api.bal b/ballerina/xml_api.bal index b8d7c16..496fc07 100644 --- a/ballerina/xml_api.bal +++ b/ballerina/xml_api.bal @@ -469,7 +469,7 @@ isolated function addNamespaces(map allNamespaces, map namespace # # + schema - A `string` representing the XSD content or a Ballerina record type representing the XSD. # + xmlValue - The XML document that needs to be validated against the schema. -# + return - Returns `true` if the XML is valid according to the schema, otherwise returns `false`. +# + return - Returns `()` if the XML is valid according to the schema, otherwise returns `Error`. # # # Examples # @@ -478,14 +478,14 @@ isolated function addNamespaces(map allNamespaces, map namespace # # `; # xml bookXml = xml `Sample`; -# boolean isValid = validate(xsdContent, bookXml); +# Error? isValid = validate(xsdContent, bookXml); # # // Using Ballerina record to represent XSD # type xsdRecord record {string name;}; -# boolean isValid = validate(xsdRecord, bookXml); +# Error? isValid = validate(xsdRecord, bookXml); # ``` public function validate(string|typedesc schema, xml xmlValue) - returns boolean = @java:Method {'class: "io.ballerina.lib.data.xmldata.xml.Native"} external; + returns Error? = @java:Method {'class: "io.ballerina.lib.data.xmldata.xml.Native"} external; public isolated function fromRecordToXml(json jsonValue, JsonOptions options, typedesc inputType) returns xml|Error = @java:Method {'class: "io.ballerina.lib.data.xmldata.utils.ToXmlUtils"} external; 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 f48d4be..21fa9fd 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 @@ -53,7 +53,8 @@ public enum DiagnosticErrorCode { INCORRECT_ELEMENT_ORDER("XML_ERROR_0025", "incorrect.element.order"), INVALID_SEQUENCE_ANNOTATION("XML_ERROR_0026", "invalid.sequence.annotation"), INVALID_CHOICE_ANNOTATION("XML_ERROR_0027", "invalid.choice.annotation"), - INVALID_XSD_ANNOTATION("XML_ERROR_0027", "invalid.xsd.annotation"); + INVALID_XSD_ANNOTATION("XML_ERROR_0028", "invalid.xsd.annotation"), + INVALID_XML("XML_ERROR_0029", "invalid.xml"); String diagnosticId; String messageKey; diff --git a/native/src/main/java/io/ballerina/lib/data/xmldata/xml/Native.java b/native/src/main/java/io/ballerina/lib/data/xmldata/xml/Native.java index 33b1e9a..d963145 100644 --- a/native/src/main/java/io/ballerina/lib/data/xmldata/xml/Native.java +++ b/native/src/main/java/io/ballerina/lib/data/xmldata/xml/Native.java @@ -82,7 +82,7 @@ public static Object validate(Object xsd, BXml xml) { try { return XSDValidator.validate(xsd, xml); } catch (Exception e) { - return DiagnosticLog.error(DiagnosticErrorCode.XML_PARSE_ERROR, e.getMessage()); + return DiagnosticLog.error(DiagnosticErrorCode.INVALID_XML, e.getMessage()); } } } diff --git a/native/src/main/java/io/ballerina/lib/data/xmldata/xml/XSDValidator.java b/native/src/main/java/io/ballerina/lib/data/xmldata/xml/XSDValidator.java index ffe02a5..1b7cc2d 100644 --- a/native/src/main/java/io/ballerina/lib/data/xmldata/xml/XSDValidator.java +++ b/native/src/main/java/io/ballerina/lib/data/xmldata/xml/XSDValidator.java @@ -18,22 +18,28 @@ package io.ballerina.lib.data.xmldata.xml; -import io.ballerina.runtime.api.PredefinedTypes; +import io.ballerina.lib.data.xmldata.utils.DiagnosticErrorCode; +import io.ballerina.lib.data.xmldata.utils.DiagnosticLog; +import io.ballerina.lib.data.xmldata.utils.ModuleUtils; import io.ballerina.runtime.api.creators.ValueCreator; import io.ballerina.runtime.api.utils.StringUtils; import io.ballerina.runtime.api.values.BError; +import io.ballerina.runtime.api.values.BMap; import io.ballerina.runtime.api.values.BString; import io.ballerina.runtime.api.values.BTypedesc; import io.ballerina.runtime.api.values.BXml; import org.w3c.dom.Document; import org.xml.sax.InputSource; +import org.xml.sax.SAXException; import java.io.File; +import java.io.IOException; import java.io.StringReader; import javax.xml.XMLConstants; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.dom.DOMSource; import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; @@ -45,14 +51,23 @@ * @since 1.1.0 */ public class XSDValidator { - public static boolean validate(Object xsd, BXml xml) { - if (xsd instanceof BString) { - return validateXmlFromXsdFile(xsd.toString(), xml); + private static final String SOURCE_OPTIONS = "SourceOptions"; + private static final String CONTENT_FIELD = "#content"; + private static final BString ATTRIBUTE_PREFIX = StringUtils.fromString("attributePrefix"); + private static final BString TEXT_FIELD_NAME = StringUtils.fromString("textFieldName"); + public static Object validate(Object xsd, BXml xml) throws ParserConfigurationException, IOException, SAXException { + try { + if (xsd instanceof BString) { + return validateXmlFromXsdFile(xsd.toString(), xml); + } + return validateXsdFromXsdRecord((BTypedesc) xsd, xml); + } catch (Exception e) { + throw e; } - return validateXsdFromXsdRecord((BTypedesc) xsd, xml); } - private static boolean validateXmlFromXsdFile(String xsdFilePath, BXml xml) { + private static Object validateXmlFromXsdFile(String xsdFilePath, BXml xml) + throws ParserConfigurationException, IOException, SAXException { try { DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); dbFactory.setIgnoringComments(true); // Ignore comments in the XML @@ -64,22 +79,29 @@ private static boolean validateXmlFromXsdFile(String xsdFilePath, BXml xml) { Schema schema = factory.newSchema(new File(xsdFilePath)); Validator validator = schema.newValidator(); validator.validate(source); - return true; + return null; } catch (Exception e) { - return false; + throw e; } } - private static boolean validateXsdFromXsdRecord(BTypedesc xsdRecord, BXml xml) { + private static Object validateXsdFromXsdRecord(BTypedesc xsdRecord, BXml xml) { try { - Object result = XmlTraversal.traverse(xml, - ValueCreator.createMapValue(PredefinedTypes.TYPE_STRING), xsdRecord); - if (result instanceof BError) { - return false; + Object result = XmlTraversal.traverse(xml, getDefaultSourceOptions(), xsdRecord); + if (result instanceof BError e) { + throw DiagnosticLog.error(DiagnosticErrorCode.INVALID_XML, e.getMessage()); } - return true; } catch (Exception e) { - return false; + throw e; } + return null; + } + + private static BMap getDefaultSourceOptions() { + BMap sourceOptions = ValueCreator + .createRecordValue(ModuleUtils.getModule(), SOURCE_OPTIONS); + sourceOptions.put(ATTRIBUTE_PREFIX, StringUtils.fromString("")); + sourceOptions.put(TEXT_FIELD_NAME, StringUtils.fromString(CONTENT_FIELD)); + return sourceOptions; } } diff --git a/native/src/main/resources/error.properties b/native/src/main/resources/error.properties index cbe8da4..f155b3f 100644 --- a/native/src/main/resources/error.properties +++ b/native/src/main/resources/error.properties @@ -103,3 +103,6 @@ error.invalid.choice.annotation=\ error.invalid.xsd.annotation=\ Cannot include xsd annotation into ''{0}'' of type ''{1}'' + +error.invalid.xml=\ + Invalid XML found: ''{0}''