Here is a full repro.
Initial setup, four files: 1) XML: e:\Temp\XSD_CACHE\input.xml 2) XSD: e:\Temp\XSD_CACHE\state.xsd 3) XQuery: c:\Program Files (x86)\BaseX\webapp\XSD11_Validation_RECEIPT_2.xq 4) c# file making BaseX REST HTTP call
XML file: e:\Temp\XSD_CACHE\input.xml ====================================== <?xml version="1.0"?> <root> <state>FL</state> <state>TX</state> </root>
XSD file: e:\Temp\XSD_CACHE\state.xsd ========================================= <?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" version="1.0.0"> <xs:element name="root"> xs:complexType xs:sequence <xs:element maxOccurs="unbounded" ref="state"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="state" type="state_type"/> <xs:simpleType name="state_type"> <xs:restriction base="xs:string"> <xs:length value="2"/> <xs:enumeration value="FL"/> <!--<xs:enumeration value="TX"/>--> </xs:restriction> </xs:simpleType> </xs:schema>
XQuery file: XSD11_Validation_RECEIPT_2.xq ========================================== declare variable $xml as xs:string external; declare variable $xsd as xs:string external;
try { let $timezone := timezone-from-dateTime(current-dateTime()) let $before_datetime := adjust-dateTime-to-timezone(convert:integer-to-dateTime(prof:current-ms()), xs:dayTimeDuration($timezone)) (: current-dateTime() :) let $result := validate:xsd-report($xml, $xsd, map { 'http://apache.org/xml/features/validation/cta-full-xpath-checking': true(), 'cache': true() }) let $after_datetime := adjust-dateTime-to-timezone(convert:integer-to-dateTime(prof:current-ms()), xs:dayTimeDuration($timezone)) (: current-dateTime() :)
return <root><metadata> <result>{data($result/status)}</result> <errors>{count($result/message[@level="Error"])}</errors> <warnings>{count($result/message[@level="Warning"])}</warnings> <startTime>{$before_datetime}</startTime> <endTime>{$after_datetime}</endTime> <xmlFile>{$xml}</xmlFile> <xsdFile>{$xsd}</xsdFile> <xsdProcessor>BaseX {data(db:system()//version)}, Java {proc:property('java.vendor')} v.{proc:property('java.runtime.version')}, {validate:xsd-processor()} 2.12.2</xsdProcessor> <xsdVersion>{data(doc($xsd)/*:schema/@version)}</xsdVersion> </metadata> <messages>{ $result/message transform with { delete node @url } }</messages> </root> } catch * { <error> <errorCode>{$err:code}</errorCode> <errorDescription>{$err:description}</errorDescription> </error> }
c# REST HTTP call: ================== void Main() { const string HOST = "HostName"; const int PORT = 8080; const string USERNAME = "username"; const string PASSWORD = "password"; System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
const string XQUERY = "XSD11_Validation_RECEIPT_2.xq"; string xmlFile = @"e:\Temp\XSD_CACHE\input.xml"; string xsdFile = @"e:\Temp\XSD_CACHE\state.xsd"; string REQUESTURL = $"http://%7BHOST%7D:%7BPORT%7D/rest?run=%7BXQUERY%7D&$xml=%7BxmlFile%7D&am..."; try { using (HttpClientHandler handler = new HttpClientHandler() {UseDefaultCredentials = true}) // for mdpd proxy //{UseDefaultCredentials = true, UseProxy = true, DefaultProxyCredentials = CredentialCache.DefaultNetworkCredentials}) using (HttpClient client = new HttpClient(handler)) { // Encode username and password pair with a base64 implementation. String encoded = Convert.ToBase64String(Encoding.UTF8.GetBytes(USERNAME + ":" + PASSWORD)); client.DefaultRequestHeaders.Add("Authorization", "Basic " + encoded); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));
var response = client.GetAsync(REQUESTURL).Result;
System.Net.Http.HttpContent content = response.Content; var contentString = content.ReadAsStringAsync().Result; // get the actual content string
if (response.StatusCode == HttpStatusCode.OK) // 200 //IsSuccessStatusCode == True { XDocument xdoc2 = XDocument.Parse(contentString); Console.WriteLine(xdoc2); string fileRECEIPT = $@"{Path.Combine(Path.GetDirectoryName(xmlFile), Path.GetFileNameWithoutExtension(xmlFile))}_RECEIPT_{DateTime.Now.ToString(" yyyy-MM-ddTHH-mm-ss")}.xml"; xdoc2.Save(fileRECEIPT, SaveOptions.None); } else { string fileErrorResponse = $@"{Path.Combine(Path.GetDirectoryName(xmlFile), Path.GetFileNameWithoutExtension(xmlFile))}_ErrorResponse_{DateTime.Now.ToSt ring("yyyy-MM-ddTHH-mm-ss")}.xml"; File.WriteAllText(fileErrorResponse, contentString); } } } catch (Exception ex) { ex.Message.Dump(); } }
In BaseX GUI: SET BINDINGS xml=e:\Temp\XSD_CACHE\input.xml,xsd=e:\Temp\XSD_CACHE\state.xsd
Start BaseX HTTP listener via launching c:\Program Files (x86)\BaseX\bin\basexhttp.bat
First execution emits the following correct result in both BaseX GUI as well as c# REST HTTP: ============================================================================ ================= <root> <metadata> <result>invalid</result> <errors>2</errors> <warnings>0</warnings> <startTime>2024-12-29T21:00:55.659-05:00</startTime> <endTime>2024-12-29T21:00:55.729-05:00</endTime> <xmlFile>e:\Temp\XSD_CACHE\input.xml</xmlFile> <xsdFile>e:\Temp\XSD_CACHE\state.xsd</xsdFile> <xsdProcessor>BaseX 11.6, Java Eclipse Adoptium v.22.0.2+9, Xerces 2.12.2</xsdProcessor> <xsdVersion>1.0.0</xsdVersion> </metadata> <messages> <message level="Error" line="4" column="19">cvc-enumeration-valid: Value 'TX' is not facet-valid with respect to enumeration '[FL]'. It must be a value from the enumeration.</message> <message level="Error" line="4" column="19">cvc-type.3.1.3: The value 'TX' of element 'state' is not valid.</message> </messages> </root>
Modified XSD file: xsd=e:\Temp\XSD_CACHE\state.xsd 1) attribute version="1.0.1" 2) uncommented <xs:enumeration value="TX"/> to make XML file valid ========================================================== <?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" version="1.0.1"> <xs:element name="root"> xs:complexType xs:sequence <xs:element maxOccurs="unbounded" ref="state"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="state" type="state_type"/> <xs:simpleType name="state_type"> <xs:restriction base="xs:string"> <xs:length value="2"/> <xs:enumeration value="FL"/> <xs:enumeration value="TX"/> </xs:restriction> </xs:simpleType> </xs:schema>
Execute in BaseX GUI: validate:xsd-init()
Re-run c# REST HTTP CALL emits incorrect result. It shows correct xsdVersion: 1.0.1, but result is invalid with the same error ============================================================================ = <root> <metadata> <result>invalid</result> <errors>2</errors> <warnings>0</warnings> <startTime>2024-12-29T21:20:07.457-05:00</startTime> <endTime>2024-12-29T21:20:07.459-05:00</endTime> <xmlFile>e:\Temp\XSD_CACHE\input.xml</xmlFile> <xsdFile>e:\Temp\XSD_CACHE\state.xsd</xsdFile> <xsdProcessor>BaseX 11.6, Java Eclipse Adoptium v.22.0.2+9, Xerces 2.12.2</xsdProcessor> <xsdVersion>1.0.1</xsdVersion> </metadata> <messages> <message level="Error" line="4" column="19">cvc-enumeration-valid: Value 'TX' is not facet-valid with respect to enumeration '[FL]'. It must be a value from the enumeration.</message> <message level="Error" line="4" column="19">cvc-type.3.1.3: The value 'TX' of element 'state' is not valid.</message> </messages> </root>
Though executing XSD11_Validation_RECEIPT_2.xq directly in the BaseX GUI emits the correct result: <root> <metadata> <result>valid</result> <errors>0</errors> <warnings>0</warnings> <startTime>2024-12-29T21:23:51.738-05:00</startTime> <endTime>2024-12-29T21:23:51.739-05:00</endTime> <xmlFile>e:\Temp\XSD_CACHE\input.xml</xmlFile> <xsdFile>e:\Temp\XSD_CACHE\state.xsd</xsdFile> <xsdProcessor>BaseX 11.6, Java Eclipse Adoptium v.22.0.2+9, Xerces 2.12.2</xsdProcessor> <xsdVersion>1.0.1</xsdVersion> </metadata> <messages/> </root>
Just restart of the BaseX HTTP listener resolves the issue with the BaseX REST HTTP call.
Regards, Yitzhak Khabinsky
Execute in BaseX GUI: validate:xsd-init() Re-run c# REST HTTP CALL emits incorrect result.
Note that the GUI runs in an independent JVM; it does not influence HTTP calls.
If I got you wrong, please strip everything that does not seem to contribute to the erroneous behavior; see [1] for more information.
Best, Christian
basex-talk@mailman.uni-konstanz.de