Project

Profile

Help

Is there any example on how to set a character map on the Saxon API in SaxonCS?

Added by Martin Honnen over 2 years ago

I am trying to use a character map created in C# with the Saxon API in SaxonCS, I have not been able to find an example and my own attempt to create one always gives an exception "Character map 'Q{}my-map' has not been defined":

Saxon.Api.SaxonApiException
  HResult=0x80131500
  Nachricht = Character map 'Q{}my-map' has not been defined
  Quelle = SaxonCS
  Stapelüberwachung:
   at Saxon.Hej.s9api.Serializer.getReceiver(PipelineConfiguration pipe, SerializationProperties params)
   at Saxon.Hej.s9api.XQueryEvaluator.getDestinationReceiver(Destination destination)
   at Saxon.Hej.s9api.XQueryEvaluator.run(Destination destination)
   at Saxon.Hej.s9api.XQueryEvaluator.run()
   at Saxon.Api.XQueryEvaluator.Run(IDestination destination)
   at SaxonCSCharacterMapTest.Program.Main(String[] args) in
C:\Users\marti\source\repos\SaxonCSCharacterMapTest\SaxonCSCharacterMapTest\Program.cs:line 40

on the xquery.Run call in the block

using (var sw = new StringWriter())
            {
                serializer.OutputWriter = sw;
                xquery.Run(serializer);
                result2Serialized = sw.ToString();
            }

Here is my attempt:

using System;
using System.Collections.Generic;
using System.IO;
using Saxon.Api;

namespace SaxonCSCharacterMapTest
{
    class Program
    {
        static void Main(string[] args)
        {
            var processor = new Processor();

            var serializer = processor.NewSerializer();

            serializer.SetOutputProperty(Serializer.METHOD, "xml");
            serializer.SetOutputProperty(Serializer.INDENT, "yes");

            var xquery = processor.NewXQueryCompiler().Compile(@"<items>{ (1 to 5) ! <item><name>Item {.}</name><data>{.}</data></item>}</items>").Load();

            string result1Serialized;

            using (var sw = new StringWriter())
            {
                serializer.OutputWriter = sw;
                xquery.Run(serializer);
                result1Serialized = sw.ToString();
            }

            Console.WriteLine(result1Serialized);

            serializer.SetCharacterMap(new QName("", "", "my-map"), new Dictionary<int, string>() { { 10, "\r\n" }, { 73, "XXXX" } });
            serializer.SetOutputProperty(Serializer.USE_CHARACTER_MAPS, "{}my-map");

            string result2Serialized;

            using (var sw = new StringWriter())
            {
                serializer.OutputWriter = sw;
                xquery.Run(serializer);
                result2Serialized = sw.ToString();
            }

            Console.WriteLine(result2Serialized);

            Console.WriteLine(result1Serialized == result2Serialized);

            Console.WriteLine(result2Serialized.Contains("\r\n"));

            Console.WriteLine(result2Serialized.Contains("XXXX"));
        }
    }
}

I am not sure whether I don't manage to grasp how to use the API to provide a map and give it a name and reference that or whether there is some problem with the API.


Replies (4)

Please register to reply

RE: Is there any example on how to set a character map on the Saxon API in SaxonCS? - Added by Michael Kay over 2 years ago

My immediate reaction to this example is that I'm not sure whether reusing a serializer like this, with changed properties, is supposed to work. I'll need to check,

RE: Is there any example on how to set a character map on the Saxon API in SaxonCS? - Added by Martin Honnen over 2 years ago

Even if I set up a new Serializer and use a newly compiled query, as in

          string result2Serialized;

            using (var sw = new StringWriter())
            {
                xquery = processor.NewXQueryCompiler().Compile(@"<items>{ (1 to 5) ! <item><name>Item {.}</name><data>{.}</data></item>}</items>").Load();

                serializer = processor.NewSerializer(sw);
                serializer.SetCharacterMap(new QName("", "", "my-map"), new Dictionary<int, string>() { { 10, "\r\n" }, { 73, "XXXX" } });
                serializer.SetOutputProperty(Serializer.USE_CHARACTER_MAPS, "{}my-map");

                xquery.Run(serializer);
                result2Serialized = sw.ToString();
            }

the error remains the same:

Saxon.Api.SaxonApiException
  HResult=0x80131500
  Nachricht = Character map 'Q{}my-map' has not been defined
  Quelle = SaxonCS
  Stapelüberwachung:
   at Saxon.Hej.s9api.Serializer.getReceiver(PipelineConfiguration pipe, SerializationProperties params)
   at Saxon.Hej.s9api.XQueryEvaluator.getDestinationReceiver(Destination destination)
   at Saxon.Hej.s9api.XQueryEvaluator.run(Destination destination)
   at Saxon.Hej.s9api.XQueryEvaluator.run()
   at Saxon.Api.XQueryEvaluator.Run(IDestination destination)
   at SaxonCSCharacterMapTest.Program.Main(String[] args) in C:\Users\marti\source\repos\SaxonCSCharacterMapTest\SaxonCSCharacterMapTest\Program.cs:line 44

RE: Is there any example on how to set a character map on the Saxon API in SaxonCS? - Added by Michael Kay over 2 years ago

I discovered there were no unit tests for this on the Java side, and therefore none on the C# side either. But the Java code paths are tested by virtue of some fn:transform() tests. I've added unit tests for both Java and C#; currently the Java test is working and the C# one isn't.

    (1-4/4)

    Please register to reply