Project

Profile

Help

Revision c1cc9bd8

Added by O'Neil Delpratt 5 months ago

Saxon/C bug fix to #4848 and #4847. Also some development work

View differences:

latest10/hec/Saxon.C.API/SaxonProcessor.h
436 436
/*
437 437
     * Register several native methods for one class.
438 438
     * @param libName name of the library which contains the function(s). Loads the library
439
     * @param gMethods Register native methods. Default is nullptr, also nullptr allowed in which cause assumption is made the user has added native methods using the method addNativeMethod .
439
     * @param gMethods Register native methods. Default is nullptr, also nullptr allowed in
440
     which cause assumption is made the user has added native methods using the method addNativeMethod .
440 441
 * @return bool success of registered native method
441 442
 */
442 443
    bool registerCPPFunction(char *libName, JNINativeMethod *gMethods = nullptr) {
latest10/hec/Saxon.C.API/XsltExecutable.cpp
25 25
    cppClass = lookForClass(SaxonProcessor::sxn_environ->env,
26 26
                            "net/sf/saxon/option/cpp/Xslt30Processor");
27 27

  
28
    messageListenerClass = lookForClass(SaxonProcessor::sxn_environ->env,
29
                                               "net/sf/saxon/option/cpp/SaxonCMessageListener");
30

  
28 31
#ifdef DEBUG
29 32
    jmethodID debugMID = SaxonProcessor::sxn_environ->env->GetStaticMethodID(cppClass, "setDebugMode", "(Z)V");
30 33
    SaxonProcessor::sxn_environ->env->CallStaticVoidMethod(cppClass, debugMID, (jboolean)true);
......
33 36
    tunnel = false;
34 37
    selection = nullptr;
35 38
    selectionV = nullptr;
39
    saxonMessageListenerObj = nullptr;
36 40
    executableObject = exObject;
37 41
    cwdXE = curr;
38 42
}
......
926 930
}
927 931

  
928 932

  
929
void XsltExecutable::setupXslMessage(bool show, const char * filename) {
930
    if (show) {
933
void XsltExecutable::setupXslMessage(bool create, const char * filename) {
934
    if (create) {
935

  
936
        static jmethodID messageID =   (jmethodID) SaxonProcessor::sxn_environ->env->GetMethodID(messageListenerClass,
937
                                                                                    "<init>",
938
                                                                                    "(Ljava/lang/String;Ljava/lang/String;)V");
939
        if (!messageID) {
940
            std::cerr << "Error: "<<"SaxonCMessageListener" << " in " <<getDllname() << " not found\n"
941
                      << std::endl;
942

  
943
        }
944

  
931 945
        if (filename == nullptr) {
932
            setProperty("m", "on");
946
            saxonMessageListenerObj = (jobject)SaxonProcessor::sxn_environ->env->NewObject(messageListenerClass, messageID,
947
                                                                                           SaxonProcessor::sxn_environ->env->NewStringUTF("-:on"));
948
            //setProperty("m", "on");
933 949
        } else {
934
            setProperty("m", filename);
950
            saxonMessageListenerObj = (jobject)SaxonProcessor::sxn_environ->env->NewObject(messageListenerClass, messageID,
951
                                                                                           SaxonProcessor::sxn_environ->env->NewStringUTF(filename));
935 952
        }
936 953
    } else {
937 954
        setProperty("m", "off");
938 955
    }
956

  
957

  
958
}
959

  
960
XdmValue * XsltExecutable::getXslMessages(){
961

  
962
    if(saxonMessageListenerObj) {
963
        static jmethodID getmessageID = (jmethodID) SaxonProcessor::sxn_environ->env->GetMethodID(messageListenerClass,
964
                                                                                                  "getXslMessages",
965
                                                                                                  "()[Lnet/sf/saxon/s9api/XdmNode;");
966
        if (!getmessageID) {
967
            std::cerr << "Error: " << getDllname() << ".getXslMessages" << " not found\n"
968
                      << std::endl;
969

  
970
        } else {
971
            jobjectArray results = (jobjectArray) (
972
                    SaxonProcessor::sxn_environ->env->CallObjectMethod(saxonMessageListenerObj, getmessageID));
973
            int sizex = SaxonProcessor::sxn_environ->env->GetArrayLength(results);
974

  
975
            if (sizex > 0) {
976
                XdmValue *value = new XdmValue();
977

  
978
                for (int p = 0; p < sizex; ++p) {
979
                    jobject resulti = SaxonProcessor::sxn_environ->env->GetObjectArrayElement(results, p);
980
                    value->addUnderlyingValue(resulti);
981
                }
982
                SaxonProcessor::sxn_environ->env->DeleteLocalRef(results);
983
                return value;
984
            }
985
        }
986
    }
987
    return NULL;
988

  
989

  
939 990
}
940 991

  
941 992

  
latest10/hec/Saxon.C.API/XsltExecutable.h
244 244
    void setupXslMessage(bool show, const char* filename=nullptr);
245 245

  
246 246

  
247

  
248
    /**
249
    * Get the messages written using the <code>xsl:message</code> instruction
250
    * @return XdmValue - Messages returned as a sequence of XdmNode objects within an XdmValue object.
251
    */
252
    XdmValue * getXslMessages();
253

  
254

  
247 255
    /**
248 256
     * Produce a representation of the compiled stylesheet, in XML form, suitable for
249 257
     * distribution and reloading. If the configuration under which the export takes place
......
470 478

  
471 479

  
472 480
    jclass  cppClass;
473
	jobject executableObject, selection;
481
    jclass messageListenerClass;
482
	jobject executableObject, selection, saxonMessageListenerObj;
474 483
	XdmValue * selectionV;
475 484
    std::string cwdXE; /*!< current working directory */
476 485
	bool tunnel, jitCompilation;
latest10/hec/Saxon.C.API/python-saxon/saxonc.pyx
3393 3393
        """
3394 3394
        cdef const char* c_string = self.thisvptr.toString()
3395 3395
        ustring = c_string.decode('UTF-8') if c_string is not NULL else None
3396
        return ustring 
3396
        return ustring
3397

  
3398
     def __iter__(self):
3399
        ''' Returns the Iterator object of PyXdmValue'''
3400
        return PyXdmValueIterator(self)
3401

  
3402
cdef class PyXdmValueIterator:
3403
     ''' Iterator class for the PyXdmValue '''
3404
     def __init__(self, value):
3405
     # PyXdmValue object reference
3406
        self._value = value
3407
        # member variable to keep track of current index
3408
       self._index = 0
3409
   def __next__(self):
3410
       ''''Returns the next value from PyXdmValue object's lists '''
3411
       if self._index < self._value.size :
3412
           result = value.item_at(self._index)
3413
           self._index +=1
3414
           return result
3415
       # End of Iteration
3416
       raise StopIteration
3417

  
3418

  
3397 3419

  
3398 3420
cdef class PyXdmItem(PyXdmValue):
3399 3421
     cdef saxoncClasses.XdmItem *derivedptr      # hold a C++ instance which we're wrapping
latest10/hec/Saxon.C.API/python-saxon/test_saxonc.py
863 863
    value = xp.evaluate('//person')
864 864
    assert isinstance(value, PyXdmValue)
865 865
    assert value.size == 3
866

  
867

  
868
def test_xdm_value_iter():
869
    xml = """\
870
    <out>
871
        <person att1='value1' att2='value2'>text1</person>
872
        <person>text2</person>
873
        <person>text3</person>
874
    </out>
875
    """
876
    sp = PySaxonProcessor()
877
    xp = sp.new_xpath_processor()
878

  
879
    node = sp.parse_xml(xml_text=xml)
880
    assert isinstance(node, PyXdmNode)
881
    xp.set_context(xdm_item=node)
882
    value = xp.evaluate('//person')
883
    assert value.size == 3
884
    for item in value:
885
        assert isinstance(item, PyXdmItem)
886

  
887

  
888
def test_xdm_value_iter2():
889
    xml = """\
890
    <out>
891
        <person att1='value1' att2='value2'>text1</person>
892
        <person>text2</person>
893
        <person>text3</person>
894
    </out>
895
    """
896
    sp = PySaxonProcessor()
897
    xp = sp.new_xpath_processor()
898

  
899
    node = sp.parse_xml(xml_text=xml)
900
    assert isinstance(node, PyXdmNode)
901
    xp.set_context(xdm_item=node)
902
    value = xp.evaluate('//person')
903
    assert value.size == 3
904
    for item in value:
905
        assert 'test.' in item__str__()
906

  
866 907
    
867 908

  
868 909
def test_single():
......
894 935
    result = xpath_processor.evaluate('$s1')
895 936

  
896 937
    assert result is not None
897
    assert'test.' in result.head.string_value
938
    assert 'test.' in result.head.string_value
898 939

  
899 940

  
900 941
def test_declare_variable_value2(saxonproc):
latest10/hec/samples/php/xslt30_PHPUnit.php
193 193

  
194 194
    }
195 195

  
196
    public function testTransformWithoutArgument1(): void
197
    {
198

  
199
        $transformer = self::$saxonProc->newXslt30Processor();
200

  
201

  
202
        $foo_xml = "trax/xml/foo.xml";
203
        $transformer->compileFromAssociatedFile($foo_xml);
204
        $transformer->setInitialMatchSelectionAsFile($foo_xml);
205
        $result = $transformer->transformToString();
206

  
207
        $this->assertNotNull($result);
208

  
209
    }
210

  
211
    public function testTransformWithoutArgument2(): void
212
    {
213

  
214
        $transformer = self::$saxonProc->newXslt30Processor();
215

  
216

  
217
        $foo_xml = "trax/xml/foo.xml";
218
        $transformer->compileFromAssociatedFile($foo_xml);
219
        $transformer->setInitialMatchSelectionAsFile($foo_xml);
220
        $resultValue = $transformer->transformToValue();
221
        $this->assertNotNull($resultValue);
222
        $resultItem = $resultValue->getHead();
223
        $this->assertNotNull($resultItem);
224
        $result = $resultItem->getStringValue();
225
        $this->assertNotNull($result);
226

  
227
    }
228

  
229

  
230

  
231
    public function testTransformWithoutArgument3(): void
232
    {
233

  
234
        $transformer = self::$saxonProc->newXslt30Processor();
235

  
236

  
237
        $foo_xml = "trax/xml/foo.xml";
238
        $transformer->compileFromAssociatedFile($foo_xml);
239
        $transformer->setInitialMatchSelectionAsFile($foo_xml);
240
        $transformer->setOutputFile("resultForTransformWithoutArgument.xml");
241
        $transformer->transformToFile();
242
        $this->assertTrue(file_exists("resultForTransformWithoutArgument.xml"));
243

  
244
                if (file_exists("resultForTransformWithoutArgument.xml")) {
245
                    unlink("resultForTransformWithoutArgument.xml");
246
                }
247

  
248
    }
249

  
196 250

  
197 251
    public function testNullStylesheet(): void
198 252
    {
latest10/hej/net/sf/saxon/option/cpp/SaxonCMessageListener.java
1 1
package net.sf.saxon.option.cpp;
2 2

  
3
import net.sf.saxon.s9api.MessageListener;
3
import net.sf.saxon.s9api.MessageListener2;
4
import net.sf.saxon.s9api.QName;
4 5
import net.sf.saxon.s9api.SaxonApiException;
5 6
import net.sf.saxon.s9api.XdmNode;
6 7

  
7 8
import javax.xml.transform.SourceLocator;
8 9
import java.io.*;
10
import java.util.ArrayList;
11
import java.util.List;
9 12

  
10
public class SaxonCMessageListener implements MessageListener {
13
public class SaxonCMessageListener implements MessageListener2 {
11 14

  
12 15

  
13 16
    int mode = 0;
14 17
    String messageFilename = null;
15 18
    File file = null;
19
    List<XdmNode> xslMessages = new ArrayList<>();
16 20

  
17 21
    public SaxonCMessageListener(String cwd, String mode) throws SaxonApiException {
18 22
        if (mode.equals("-:on")) {
......
20 24

  
21 25
        } else if (mode.equals("-:off")) {
22 26
            this.mode = 0;
23
        } else {
27
        }  else {
24 28
            this.mode = 2;
25
            messageFilename = cwd + mode;
29
            messageFilename = cwd + mode.substring(1);
26 30
            file = SaxonCAPI.resolveFile(cwd, messageFilename);
27 31

  
28 32
        }
29 33
    }
30 34

  
31
    public void message(XdmNode content, boolean terminate, SourceLocator locator) {
32 35

  
33
        if (mode == 1) {
36
    @Override
37
    public void message(XdmNode content, QName errorCode, boolean terminate, SourceLocator locator) {
38
        if(mode == 0 ) {
39
            return;
40
        } else if (mode == 1) {
41
            xslMessages.add(content);
34 42
            System.err.println(content.getStringValue());
35 43
        } else if (mode == 2) {
36

  
44
            xslMessages.add(content);
37 45
            try (FileWriter fw = new FileWriter(file, true);
38 46
                 BufferedWriter bw = new BufferedWriter(fw);
39 47
                 PrintWriter out = new PrintWriter(bw)) {
......
44 52
            }
45 53

  
46 54
        }
55
    }
47 56

  
48 57

  
49
        //xslMessages.add(content);
58
    /**
59
     * Get the xsl:messages  as an array of XdmNode objects
60
     * @return array of XdmNode objects
61
     */
62
    public XdmNode[] getXslMessages() {
63
        if(xslMessages == null) {
64
            return null;
65
        } else {
66
            return xslMessages.toArray(new XdmNode[xslMessages.size()]);
67
        }
50 68
    }
51 69

  
70

  
52 71
}

Also available in: Unified diff