Bug #5134
closedSaxonCS fails if the local culture of the machine is not en-GB (or similar)
100%
Description
I have made a new .Net 5 solution in Visual Studio. Added Examples.cs, samples/data and samples/styles from saxon-resources-11 in project SaxonEE. Added NuGet package SaxonCS v11.0.1 to the project. Added a xUnit tests project to run all 48 examples. I have an evaluation license for Saxon-EE. Almost all examples result with errors deep inside Saxon. I get the same result if I run SaxonEE.exe in a Command Prompt. What's wrong?
44 of 48 examples result with System.TypeInitializationException:
E.g.: XdmNavigation
System.TypeInitializationException The type initializer for 'Saxon.Eej.functions.extfn.EXPathFileFunctionSet' threw an exception. at Saxon.Eej.functions.extfn.EXPathFileFunctionSet.getInstance() at Saxon.Eej.config.EnterpriseConfiguration.getBuiltInExtensionLibraryList() at Saxon.Hej.sxpath.AbstractStaticContext.setDefaultFunctionLibrary(Int32 version) at Saxon.Hej.sxpath.IndependentContext..ctor(Configuration config) at Saxon.Eej.config.ProfessionalConfiguration.getSystemFunction(StructuredQName name, Int32 arity) at Saxon.Api.Processor.GetSystemFunction(QName name, Int32 arity) at SaxonEE.XdmNavigation.run(Uri samplesDir) in C:\Git\SaxonCS\SaxonEE\Examples.cs:line 264 at Tests.UnitTests.ExampleTest(Int32 index) in C:\Git\SaxonCS\Tests\UnitTests.cs:line 129
System.FormatException Input string was not in a correct format. at Singulink.Numerics.BigDecimal.Parse(ReadOnlySpan`1 s, NumberStyles style, IFormatProvider formatProvider) at Saxon.Eej.functions.extfn.EXPathFileFunctionSet..cctor()
XPathSchemaAware result with System.FormatException:
System.FormatException Input string was not in a correct format. at Singulink.Numerics.BigDecimal.Parse(ReadOnlySpan`1 s, NumberStyles style, IFormatProvider formatProvider) at Saxon.Eej.ee.schema.sdoc.VersionControlFilter..ctor(SchemaCompiler compiler, Receiver next) at Saxon.Eej.ee.schema.sdoc.SchemaReader.buildSchemaDocument(Source source, SchemaCompiler compiler, PipelineConfiguration pipe, SchemaElement referrer) at Saxon.Eej.ee.schema.sdoc.SchemaReader.read(Source source, SchemaCompiler compiler, PipelineConfiguration pipe, SchemaElement referrer) at Saxon.Eej.config.EnterpriseConfiguration.addSchemaSource(Source schemaSource, ErrorReporter errorReporter, SchemaCompiler compiler) at Saxon.Eej.config.EnterpriseConfiguration.addSchemaSource(Source schemaSource, ErrorReporter errorReporter) at Saxon.Eej.ee.s9api.SchemaManagerImpl.load(Source source) at Saxon.Api.SchemaManager.Compile(Uri uri) at SaxonEE.XPathSchemaAware.run(Uri samplesDir) in C:\Git\SaxonCS\SaxonEE\Examples.cs:line 2204 at Tests.UnitTests.ExampleTest(Int32 index) in C:\Git\SaxonCS\Tests\UnitTests.cs:line 129
XsltDisplayingErrors, XsltCapturingErrors and Validate are successful.
Updated by Michael Kay about 3 years ago
I think I can hazard a guess: the Singulink.Numerics.BigDecimal.Parse()
method is expecting a decimal number in a localised format depending on the current culture set on your machine, whereas we're expecting it to handle culture-neutral (or English) format.
I'll explore that to see if I can confirm it.
Updated by Mårten Sörliden about 3 years ago
Yes, setting Thread.CurrentThread.CurrentCulture = new CultureInfo("en-GB");
solved most of the problems.
Only two problems are left:
XPathWithStaticError
Saxon.Api.SaxonApiException Cannot find a 0-argument function named Q{http://www.w3.org/2005/xpath-functions}unknown() at Saxon.Hej.s9api.XPathCompiler.internalCompile(String source) at Saxon.Hej.s9api.XPathCompiler.compile(String source) at Saxon.Api.XPathCompiler.Compile(String source) at SaxonEE.XPathWithStaticError.run(Uri samplesDir) in C:\Git\SaxonCS\SaxonEE\Examples.cs:line 424 at Tests.UnitTests.ExampleTest(Int32 index) in C:\Git\SaxonCS\Tests\UnitTests.cs:line 134
XPathWithDynamicError
Saxon.Api.SaxonApiException Cannot compare xs:int to xs:string at Saxon.Hej.s9api.XPathSelector.evaluateSingle() at Saxon.Api.XPathSelector.EvaluateSingle() at SaxonEE.XPathWithDynamicError.run(Uri samplesDir) in C:\Git\SaxonCS\SaxonEE\Examples.cs:line 457 at Tests.UnitTests.ExampleTest(Int32 index) in C:\Git\SaxonCS\Tests\UnitTests.cs:line 134
Updated by Michael Kay about 3 years ago
- Subject changed from Almost all examples result with System.TypeInitializationException - SaxonCS to SaxonCS fails if the local culture of the machine is not en-GB (or similar)
- Category set to Localization
- Assignee set to Michael Kay
I think that as the names suggest, those tests are intended to demonstrate error handling, so the results are as expected.
Updated by Michael Kay about 3 years ago
I added a -locale option to the test driver, and tried running with -locale:de-DE
. The effect of the option is to set Thread.CurrentThread.CurrentCulture
. There was a minor glitch in DotNetPlatform.getDefaultCountry()
(used by format-number()) but with this fixed, everything ran smoothly.
The same is true if I set it in Examples.cs.
I was hoping this would enable me to reproduce the bug, but it seems it's not so easy.
Updated by Michael Kay about 3 years ago
Although I haven't found a way to reproduce it and therefore to test any fix, it's reasonably obvious what the fix should be. The transpiler needs to convert java new BigDecimal(%string%)
to Singulink.Numerics.BigDecimal.Parse(%string%, NumberStyles.Number, CultureInfo.InvariantCulture)
The rule for this is in transpiler/constructors.xsl line 76.
Updated by Michael Kay about 3 years ago
- Status changed from New to In Progress
- Fix Committed on Branch trunk added
I've applied the patch and it's causing no regression, but I'm leaving it open to see if I can reproduce the problem and thereby get more confidence in the fix.
Updated by Martin Honnen about 3 years ago
I see a culture dependency on serializing a decimal number, 'C:\Program Files\Saxonica\SaxonCS-11.0\SaxonCS.exe' query -qs:'1.3'
gives <?xml version="1.0" encoding="UTF-8"?>1,3
for me.
Updated by Martin Honnen about 3 years ago
Setting Set-Culture en-US
in Powershell and opening a new Powershell window makes SaxonCS return 1.3
. The previous culture info (Get-Culture
) was de-DE
.
Updated by Michael Kay about 3 years ago
Thanks Martin. I'll give it a try on Windows in due course.
Saxon's doing decimal-to-string conversion using a straightforward call on Singulink.Numerics.BigDecimal.ToString()
. Despite the fact that the documentation for this method says it uses exponential notation, this doesn't appear to be the case. The documentation doesn't mention anything about culture, but stepping through the code it's clear it uses the culture-specific decimal point, so I'll have to change it to use the static method BigDecimal.ToString(value, "G", CultureInfo.Invariant)
. The code is in an annotation on the Java method BigDecimalValue.decimalToString()
rather than in the transpiler.
Updated by Michael Kay almost 3 years ago
- Status changed from In Progress to Resolved
Closing this as we have now improved our testing on non-English locales.
Updated by O'Neil Delpratt almost 3 years ago
- % Done changed from 0 to 100
- Fixed in Maintenance Release 11.1 added
- Platforms .NET, Java added
Bug fix applied in the Saxon 11.1 release.
Updated by O'Neil Delpratt almost 3 years ago
- Status changed from Resolved to Closed
Please register to edit this issue