Project

Profile

Help

How to connect?
Download (148 KB) Statistics
| Branch: | Revision:

he / src / main / c / Saxon.C.API / python-saxon / saxonc.pyx @ 686e76e7

1
"""@package saxonc
2
This documentation details the Python API for Saxon/C, which has been written in cython for Python3.
3

    
4
Saxon/C is a cross-compiled variant of Saxon from the Java platform to the C/C++ platform.
5
Saxon/C provides processing in XSLT 3.0, XQuery 3.0/3.1 and XPath 2.0/3.0/3.1, and Schema validation 1.0/1.1.
6
Main classes in Saxon/C Python API: PySaxonProcessor, PyXsltProcessor, PyXslt30Processor, PyXQueryProcessor, PySchemaValidator, PyXdmValue, PyXdmItem, PyXdmNode and PyXdmAtomicValue."""
7

    
8

    
9
# distutils: language = c++
10

    
11
cimport saxoncClasses
12

    
13
from libcpp cimport bool
14
from libcpp.string cimport string
15
from libcpp.map cimport map
16
from nodekind import *
17
from os.path import isfile
18

    
19
cdef const char * make_c_str(str str_value):
20
    if str_value is None:
21
        return NULL
22
    else:
23
        py_string_string = str_value.encode('UTF-8') if str_value is not None else None
24
        c_string = py_string_string if str_value is not None else ""
25
        return c_string
26

    
27
cdef str make_py_str(const char * c_value):
28
    ustring = c_value.decode('UTF-8') if c_value is not NULL else None
29
    return ustring    
30
   
31

    
32
cdef class PySaxonProcessor:
33
    """An SaxonProcessor acts as a factory for generating XQuery, XPath, Schema and XSLT compilers.
34
    This class is itself the context that needs to be managed (i.e. allocation & release)
35

    
36
    Example:
37
          with saxonc.PySaxonProcessor(license=False) as proc:
38
             print("Test Saxon/C on Python")
39
             print(proc.version)
40
             xdmAtomicval = proc.make_boolean_value(False)
41
             xslt30proc = proc.new_xslt30_processor()
42
    """
43
    cdef saxoncClasses.SaxonProcessor *thisptr      # hold a C++ instance which we're wrapping
44

    
45
    ##
46
    # The Constructor
47
    # @param license Flag that a license is to be used
48
    # @contextlib.contextmanager
49
    def __cinit__(self, config_file= None, license=False):
50
        """
51
        __cinit__(self, config_file=None, license=False)
52
        The constructor.
53

    
54
        Args:
55
            config_file (str): Construct a Saxon processor based upon an configuration file
56
            license(bool): Flag that a license is to be used. The Default is false.
57
            
58
        """
59
        cdef const char * c_str = NULL
60
        cdef bool l = license
61
        if config_file is not None:
62
            c_str = make_c_str(config_file)
63
            if c_str is not NULL:
64
                self.thisptr = new saxoncClasses.SaxonProcessor(c_str)
65
            else:
66
                raise Exception("Configuration file for SaxonProcessor is None")
67
        else:
68
            self.thisptr = new saxoncClasses.SaxonProcessor(l)
69
            
70
    def __dealloc__(self):
71
        """The destructor."""
72
        del self.thisptr
73

    
74
    def __enter__(self):
75
      """enter method for use with the keyword 'with' context"""
76
      return self
77

    
78
    def __exit__(self, exception_type, exception_value, traceback):
79
        """The exit method for the context PySaxonProcessor. Here we release the Jet VM resources.
80
        If we have more than one live PySaxonProcessor object the release() method has no effect.
81
        """
82
        self.thisptr.release()
83

    
84
    property version:
85
        """
86
        Get the Saxon Version.
87

    
88
        Getter:
89
            str: The Saxon version
90
        """
91
        def __get__(self):        
92
            cdef const char* c_string = self.thisptr.version()
93
            ustring = c_string.decode('UTF-8')
94
            return ustring
95

    
96

    
97
    def release(self):
98
        """
99
        release(self) 
100
        Clean up and destroy Java VM to release memory used."""
101

    
102
        self.thisptr.release()
103

    
104

    
105
    @property
106
    def cwd(self):
107
        """
108
        cwd Property represents the current working directorty
109

    
110
        :str: Get or set the current working directory"""
111
        cdef const char* c_string = self.thisptr.getcwd()
112
        ustring = c_string.decode('UTF-8') if c_string is not NULL else None
113
        return ustring
114

    
115

    
116
    def set_cwd(self, cwd):
117
         py_value_string = cwd.encode('UTF-8') if cwd is not None else None
118
         cdef char * c_str_ = py_value_string if cwd is not None else ""
119
         self.thisptr.setcwd(c_str_)
120

    
121

    
122
    def set_resources_directory(self, dir_):
123
        """
124
        Property to set or get resources directory
125

    
126
        :str: A string of the resources directory which Saxon will use
127

    
128
        """
129

    
130
    @property
131
    def resources_directory(self):
132
        return NULL
133
    
134
    def set_configuration_property(self, name, value):
135
        """
136
        set_configuration_property(self, name, value)
137
        Set configuration property specific to the processor in use.
138
        Properties set here are common across all processors. 
139

    
140
        Args:
141
            name (str): The name of the property
142
            value (str): The value of the property
143

    
144
        Example:
145
          'l': 'on' or 'off' - to enable the line number
146

    
147
        """
148
        py_name_string = name.encode('UTF-8') if name is not None else None
149
        cdef char * c_str_ = py_name_string if name is not None else ""
150
        py_value_string = value.encode('UTF-8') if value is not None else None
151
        cdef char * c_value_str_ = py_value_string if value is not None else ""
152
        self.thisptr.setConfigurationProperty(c_str_, c_value_str_)
153

    
154
    def clear_configuration_properties(self):
155
        """
156
        clear_configuration_properties(self)
157
        Clear the configurations properties in use by the processor 
158

    
159
        """
160
        self.thisptr.clearConfigurationProperties()
161

    
162
    @property
163
    def is_schema_aware(self):
164
        """
165
        is_schema_aware(self)
166
        Property to check if the processor is Schema aware. A licensed Saxon-EE/C product is schema aware 
167

    
168
        :bool: Indicate if the processor is schema aware, True or False otherwise
169
        """
170
        return self.thisptr.isSchemaAwareProcessor()
171

    
172

    
173
    def new_xslt_processor(self):
174
        """
175
        new_xslt_processor(self)
176
        Create an PyXsltProcessor. A PyXsltProcessor is used to compile and execute XSLT stylesheets. 
177

    
178
        Returns: 
179
            PyXsltProcessor: a newly created PyXsltProcessor
180

    
181
        """
182
        cdef PyXsltProcessor val = PyXsltProcessor()
183
        val.thisxptr = self.thisptr.newXsltProcessor()
184
        return val
185

    
186
    def new_xslt30_processor(self):
187
        """
188
        new_xslt30_processor(self)
189
        Create an PyXslt30Processor. A PyXslt30Processor is used to compile and execute XSLT 3.0 stylesheets. 
190

    
191
        Returns: 
192
            PyXslt30Processor: a newly created PyXslt30Processor
193

    
194
        """
195
        cdef PyXslt30Processor val = PyXslt30Processor()
196
        val.thisxptr = self.thisptr.newXslt30Processor()
197
        return val
198

    
199
    def new_xquery_processor(self):
200
        """
201
        new_xquery_processor(self)
202
        Create an PyXqueryProcessor. A PyXQueryProcessor is used to compile and execute XQuery queries. 
203

    
204
        Returns: 
205
            PyXQueryProcessor: a newly created PyXQueryProcessor
206

    
207
        """
208
        cdef PyXQueryProcessor val = PyXQueryProcessor()
209
        val.thisxqptr = self.thisptr.newXQueryProcessor()
210
        return val
211

    
212
    def new_xpath_processor(self):
213
        """
214
        new_xpath_processor(self)
215
        Create an PyXPathProcessor. A PyXPathProcessor is used to compile and execute XPath expressions. 
216

    
217
        Returns: 
218
            PyXPathProcessor: a newly created XPathProcessor
219

    
220
        """
221
        cdef PyXPathProcessor val = PyXPathProcessor()
222
        val.thisxpptr = self.thisptr.newXPathProcessor()
223
        return val
224

    
225
    def new_schema_validator(self):
226
        """
227
        new_schema_validator(self)
228
        Create a PySchemaValidator which can be used to validate instance documents against the schema held by this 
229

    
230
        Returns: 
231
            PySchemaValidator: a newly created PySchemaValidator
232

    
233
        """
234
        cdef PySchemaValidator val = PySchemaValidator()
235
        val.thissvptr = self.thisptr.newSchemaValidator()
236
        if val.thissvptr is NULL:
237
            raise Exception("Error: Saxon Processor is not licensed for schema processing!")
238
        return val
239

    
240
    def make_string_value(self, str_):
241
        """
242
        make_string_value(self, str_)
243
        Factory method. Unlike the constructor, this avoids creating a new StringValue in the case
244
        of a zero-length string (and potentially other strings, in future)
245
        
246
        Args:
247
            str_ (str): the String value. NULL is taken as equivalent to "".
248

    
249
        Returns:
250
            PyXdmAtomicValue: The corresponding Xdm StringValue
251

    
252
        """
253
        py_value_string = str_.encode('UTF-8') if str_ is not None else None
254
        cdef char * c_str_ = py_value_string if str_ is not None else ""
255
        cdef PyXdmAtomicValue val = PyXdmAtomicValue()
256
        val.derivedaptr = val.derivedptr = val.thisvptr = self.thisptr.makeStringValue(c_str_)
257
        return val
258

    
259
    def make_integer_value(self, value):
260
        """
261
        make_integer_value(self, value)
262
        Factory method: makes either an Int64Value or a BigIntegerValue depending on the value supplied
263
        
264
        Args:
265
            value (int): The supplied primitive integer value
266

    
267
        Returns:
268
            PyXdmAtomicValue: The corresponding Xdm value which is a BigIntegerValue or Int64Value as appropriate
269

    
270
        """
271
        cdef PyXdmAtomicValue val = PyXdmAtomicValue()
272
        val.derivedaptr = val.derivedptr = val.thisvptr = self.thisptr.makeIntegerValue(value)
273
        return val
274

    
275
    def make_double_value(self, value):
276
        """
277
        make_double_value(self, value)
278
        Factory method: makes a double value
279

    
280
        Args:
281
            value (double): The supplied primitive double value 
282

    
283
        Returns:
284
            PyXdmAtomicValue: The corresponding Xdm Value
285
        """
286
        cdef PyXdmAtomicValue val = PyXdmAtomicValue()
287
        val.derivedaptr = val.derivedptr = val.thisvptr = self.thisptr.makeDoubleValue(value)
288
        return val
289

    
290
    def make_float_value(self, value):
291
        """
292
        make_float_value(self, value)
293
        Factory method: makes a float value
294

    
295
        Args:
296
            value (float): The supplied primitive float value 
297

    
298
        Returns:
299
            PyXdmAtomicValue: The corresponding Xdm Value
300
        """
301

    
302
        cdef PyXdmAtomicValue val = PyXdmAtomicValue()
303
        val.derivedaptr = val.derivedptr = val.thisvptr = self.thisptr.makeFloatValue(value)
304
        return val
305

    
306
    def make_long_value(self, value):
307
        """
308
        make_long_value(self, value)
309
        Factory method: makes either an Int64Value or a BigIntegerValue depending on the value supplied
310

    
311
        Args:
312
            value (long): The supplied primitive long value 
313

    
314
        Returns:
315
            PyXdmAtomicValue: The corresponding Xdm Value
316
        """
317
        cdef PyXdmAtomicValue val = PyXdmAtomicValue()
318
        val.derivedaptr = val.derivedptr = val.thisvptr = self.thisptr.makeLongValue(value)
319
        return val
320

    
321
    def make_boolean_value(self, value):
322
        """
323
        make_boolean_value(self, value)
324
        Factory method: makes a XdmAtomicValue representing a boolean Value
325

    
326
        Args:
327
            value (boolean): True or False, to determine which boolean value is required
328

    
329
        Returns:
330
            PyAtomicValue: The corresonding XdmValue
331
        """
332
        cdef bool c_b = value
333
        cdef PyXdmAtomicValue val = PyXdmAtomicValue()
334
        val.derivedaptr = val.derivedptr = val.thisvptr = self.thisptr.makeBooleanValue(c_b)
335
        return val
336

    
337
    def make_qname_value(self, str_):
338
        """
339
        make_qname_value(self, str_)
340
        Create an QName Xdm value from string representation in clark notation
341

    
342
        Args:
343
            str_ (str): The value given in a string form in clark notation. {uri}local
344

    
345
        Returns:
346
            PyAtomicValue: The corresonding value
347

    
348
        """
349
        py_value_string = str_.encode('UTF-8') if str_ is not None else None
350
        cdef char * c_str_ = py_value_string if str_ is not None else ""
351
        cdef PyXdmAtomicValue val = PyXdmAtomicValue()
352
        val.derivedaptr = val.derivedptr = val.thisvptr = self.thisptr.makeQNameValue(c_str_)
353
        return val
354

    
355
    def make_atomic_value(self, value_type, value):
356
        """
357
        make_atomic_value(self, value_type, value)
358
        Create an QName Xdm value from string representation in clark notation
359

    
360
        Args:
361
            str_ (str): The value given in a string form in clark notation. {uri}local
362

    
363
        Returns:
364
            PyAtomicValue: The corresonding value
365

    
366
        """
367

    
368
        py_valueType_string = value_type.encode('UTF-8') if value_type is not None else None
369
        cdef char * c_valueType_string = py_valueType_string if value_type is not None else ""
370
        cdef PyXdmAtomicValue val = PyXdmAtomicValue()
371
        val.derivedaptr = val.derivedptr = val.thisvptr = self.thisptr.makeAtomicValue(c_valueType_string, value)
372
        return val
373

    
374
    def get_string_value(self, PyXdmItem item):
375
        """
376
        get_string_value(self, PyXdmItem item)
377
        Create an QName Xdm value from string representation in clark notation
378

    
379
        Args:
380
            str_ (str): The value given in a string form in clark notation. {uri}local
381

    
382
        Returns:
383
            PyAtomicValue: The corresonding value
384

    
385
        """
386
        return self.thisptr.getStringValue(item.derivedptr)
387

    
388
    def parse_xml(self, **kwds):
389
        """
390
        parse_xml(self, **kwds)
391
        Parse a lexical representation, source file or uri of the source document and return it as an Xdm Node
392

    
393
        Args:
394
            **kwds : The possible keyword arguments must be one of the follow (xml_file_name|xml_text|xml_uri)
395

    
396
        Returns:
397
            PyXdmNode: The Xdm Node representation of the XML document
398

    
399
        Raises:
400
            Exception: Error if the keyword argument is not one of xml_file_name|xml_text|xml_uri.
401
        """
402
        py_error_message = "Error: parseXml should only contain one of the following keyword arguments: (xml_file_name|xml_text|xml_uri)"
403
        if len(kwds) != 1:
404
          raise Exception(py_error_message)
405
        cdef PyXdmNode val = None
406
        cdef py_value = None
407
        cdef char * c_xml_string = NULL
408
        if "xml_text" in kwds:
409
          py_value = kwds["xml_text"]
410
          py_xml_text_string = py_value.encode('UTF-8') if py_value is not None else None
411
          c_xml_string = py_xml_text_string if py_value is not None else "" 
412
          val = PyXdmNode()
413
          val.derivednptr = val.derivedptr = val.thisvptr = self.thisptr.parseXmlFromString(c_xml_string)
414
          return val
415
        elif "xml_file_name" in kwds:
416
          py_value = kwds["xml_file_name"]
417
          py_filename_string = py_value.encode('UTF-8') if py_value is not None else None
418
          if py_filename_string  is None or isfile(py_filename_string) == False:
419
            raise Exception("XML file does not exist")
420
          c_xml_string = py_filename_string if py_value is not None else ""
421
          val = PyXdmNode()
422
          val.derivednptr = val.derivedptr = val.thisvptr = self.thisptr.parseXmlFromFile(c_xml_string)
423
          return val 
424
        elif "xml_uri" in kwds:
425
          py_value = kwds["xml_uri"]
426
          py_uri_string = py_value.encode('UTF-8') if py_value is not None else None
427
          c_xml_string = py_uri_string if py_value is not None else ""
428
          val = PyXdmNode()
429
          val.derivednptr = val.derivedptr = val.thisvptr = self.thisptr.parseXmlFromUri(c_xml_string)
430
          return val
431
        else:
432
           raise Exception(py_error_message)
433

    
434
    def exception_occurred(self):
435
        """
436
        exception_occurred(self)
437
        Check if an exception has occurred internally within Saxon/C
438

    
439
        Returns:
440
            boolean: True or False if an exception has been reported internally in Saxon/C
441
        """
442
        return self.thisptr.exceptionOccurred()
443

    
444
    def exception_clear(self):
445
        """
446
        exceltion_clear(self)
447
        Clear any exception thrown internally in Saxon/C.
448

    
449

    
450
        """
451
        self.thisptr.exceptionClear()
452

    
453

    
454
cdef class PyXsltProcessor:
455
     """An PyXsltProcessor represents factory to compile, load and execute a stylesheet.
456
     It is possible to cache the context and the stylesheet in the PyXsltProcessor """
457

    
458
     cdef saxoncClasses.XsltProcessor *thisxptr      # hold a C++ instance which we're wrapping
459

    
460
     def __cinit__(self):
461
        """Default constructor """
462
        self.thisxptr = NULL
463
     def __dealloc__(self):
464
        if self.thisxptr != NULL:
465
           del self.thisxptr
466
     def set_cwd(self, cwd):
467
        """
468
        set_cwd(self, cwd)
469
        Set the current working directory.
470

    
471
        Args:
472
            cwd (str): current working directory
473
        """
474
        py_cwd_string = cwd.encode('UTF-8') if cwd is not None else None
475
        cdef char * c_cwd = py_cwd_string if cwd is not None else "" 
476
        self.thisxptr.setcwd(c_cwd)
477

    
478

    
479
     def set_base_output_uri(self, base_uri):
480
        """
481
        set_base_output_uri(self, base_uri)
482
        Set the base output URI. The default is the base URI of the principal output
483
        of the transformation. If a base output URI is supplied using this function then it takes precedence
484
        over any base URI defined in the principal output, and
485
        it may cause the base URI of the principal output to be modified in situ.
486
        The base output URI is used for resolving relative URIs in the 'href' attribute
487
        of the xsl:result-document instruction; it is accessible to XSLT stylesheet
488
        code using the XPath {@code current-output-uri()} function.
489

    
490
        Args:
491
            base_uri (str): the base output URI
492
        """
493
        py_uri_string = base_uri.encode('UTF-8') if base_uri is not None else None
494
        cdef char * c_uri = py_uri_string if base_uri is not None else ""
495
        self.thisxptr.setBaseOutputURI(c_uri)
496

    
497
     def set_source(self, **kwds):
498
        """Set the source document for the transformation.
499

    
500
        Args:
501
            **kwds: Keyword argument can only be one of the following: file_name|xdm_node
502
        Raises:
503
            Exception: Exception is raised if keyword argument is not one of file_name or node.
504
        """
505

    
506
        py_error_message = "Error: setSource should only contain one of the following keyword arguments: (file_name|xdm_node)"
507
        if len(kwds) != 1:
508
          raise Exception(py_error_message)
509
        cdef py_value = None
510
        cdef py_value_string = None
511
        cdef char * c_source
512
        cdef PyXdmNode xdm_node = None
513
        if "file_name" in kwds:
514
            py_value = kwds["file_name"]
515
            py_value_string = py_value.encode('UTF-8') if py_value is not None else None
516
            c_source = py_value_string if py_value is not None else "" 
517
            self.thisxptr.setSourceFromFile(c_source)
518
        elif "xdm_node" in kwds:
519
            xdm_node = kwds["xdm_node"]
520
            self.thisxptr.setSourceFromXdmNode(xdm_node.derivednptr)
521
        else:
522
          raise Exception(py_error_message)
523

    
524
     def set_output_file(self, output_file):
525
        """
526
        set_output_file(self, output_file)
527
        Set the output file where the output of the transformation will be sent
528

    
529
        Args:
530
            output_file (str): The output file supplied as a str
531

    
532
        """
533
        py_filename_string = output_file.encode('UTF-8') if output_file is not None else None
534
        cdef char * c_outputfile = py_filename_string if output_file is not None else ""
535
        self.thisxptr.setOutputFile(c_outputfile)
536

    
537
     def set_jit_compilation(self, bool jit):
538
        """
539
        set_jit_compilation(self, jit)
540
        Say whether just-in-time compilation of template rules should be used.
541

    
542
        Args:
543
            jit (bool): True if just-in-time compilation is to be enabled. With this option enabled,
544
                static analysis of a template rule is deferred until the first time that the
545
                template is matched. This can improve performance when many template
546
                rules are rarely used during the course of a particular transformation; however,
547
                it means that static errors in the stylesheet will not necessarily cause the
548
                compile(Source) method to throw an exception (errors in code that is
549
                actually executed will still be notified but this may happen after the compile(Source)
550
                method returns). This option is enabled by default in Saxon-EE, and is not available
551
                in Saxon-HE or Saxon-PE.
552
                Recommendation: disable this option unless you are confident that the
553
                stylesheet you are compiling is error-free. 
554

    
555
        """
556
        cdef bool c_jit
557
        c_jit = jit
558
        self.thisxptr.setJustInTimeCompilation(c_jit)
559
        #else:
560
        #raise Warning("setJustInTimeCompilation: argument must be a boolean type. JIT not set")
561
     def set_parameter(self, name, PyXdmValue value):
562
        """
563
        set_parameter(self, PyXdmValue value)
564
        Set the value of a stylesheet parameter
565

    
566
        Args:
567
            name (str): the name of the stylesheet parameter, as a string. For namespaced parameter use the JAXP solution i.e. "{uri}name
568
            value (PyXdmValue): the value of the stylesheet parameter, or NULL to clear a previously set value
569

    
570
        """
571
        cdef const char * c_str = make_c_str(name)
572
        if c_str is not NULL:
573
            value.thisvptr.incrementRefCount()
574
            self.thisxptr.setParameter(c_str, value.thisvptr)
575

    
576
     def get_parameter(self, name):
577
        """
578
        get_parameter(self, name)
579
        Get a parameter value by a given name
580

    
581
        Args:
582
            name (str): The name of the stylesheet parameter
583

    
584
        Returns:
585
            PyXdmValue: The Xdm value of the parameter  
586

    
587

    
588
        """
589
        py_name_string = name.encode('UTF-8') if name is not None else None
590
        cdef char * c_name = py_name_string if name is not None else ""
591
        cdef PyXdmValue val = PyXdmValue()
592
        val.thisvptr = self.thisxptr.getParameter(c_name)
593
        return val
594

    
595
     def remove_parameter(self, name):
596
        """
597
        remove_parameter(self, name)
598
        Remove the parameter given by name from the PyXsltProcessor. The parameter will not have any affect on the stylesheet if it has not yet been executed
599

    
600
        Args:
601
            name (str): The name of the stylesheet parameter
602

    
603
        Returns:
604
            bool: True if the removal of the parameter has been successful, False otherwise.
605

    
606
        """
607

    
608
        py_name_string = name.encode('UTF-8') if name is not None else None
609
        cdef char * c_name = py_name_string if name is not None else ""
610
        return self.thisxptr.removeParameter(c_name)
611

    
612
     def set_property(self, name, value):
613
        """
614
        set_property(self, name, value)
615
        Set a property specific to the processor in use.
616
 
617
        Args:
618
            name (str): The name of the property
619
            value (str): The value of the property
620

    
621
        Example:
622
            XsltProcessor: set serialization properties (names start with '!' i.e. name "!method" -> "xml")\r
623
            'o':outfile name,\r
624
            'it': initial template,\r 
625
            'im': initial mode,\r
626
            's': source as file name\r
627
            'm': switch on message listener for xsl:message instructions,\r
628
            'item'| 'node' : source supplied as an XdmNode object,\r
629
            'extc':Set the native library to use with Saxon for extension functions written in C/C++/PHP\r
630

    
631
        """
632

    
633
        py_name_string = name.encode('UTF-8') if name is not None else None
634
        cdef char * c_name = py_name_string if name is not None else ""
635
        py_value_string = value.encode('UTF-8') if value is not None else None
636
        cdef char * c_value = py_value_string if value is not None else ""
637
        self.thisxptr.setProperty(c_name, c_value)
638

    
639
     def clear_parameters(self):
640
        """
641
        clear_parameter(self)
642
        Clear all parameters set on the processor for execution of the stylesheet
643
        """
644

    
645
        self.thisxptr.clearParameters()
646
     def clear_properties(self):
647
        """
648
        clear_properties(self)
649
        Clear all properties set on the processor
650
        """
651

    
652
        self.thisxptr.clearProperties()
653

    
654
     def setup_xsl_message(self, show, file_name = None):
655
        """
656
        setup_xsl_message(self, **kwds)
657
        gives users the option to switch on or off the <code>xsl:message</code> feature. It is also possible
658
        to send the <code>xsl:message</code> outputs to file given by file name.
659

    
660
        """
661
        py_name_string = file_name.encode('UTF-8') if file_name is not None else None
662
        cdef char * c_file_name = py_name_string if file_name is not None else NULL
663
        self.thisxptr.getXslMessages(bool(show), c_file_name)
664

    
665

    
666
     def transform_to_string(self, **kwds):
667
        """
668
        transform_to_string(self, **kwds)
669
        Execute transformation to string.
670

    
671
        Args:
672
            **kwds: Possible arguments: source_file (str) or xdm_node (PyXdmNode). Other allowed argument: stylesheet_file (str)
673

    
674

    
675
        Example:
676

    
677
            1) result = xsltproc.transform_to_string(source_file="cat.xml", stylesheet_file="test1.xsl")
678

    
679
            2) xsltproc.set_source("cat.xml")\r
680
               result = xsltproc.transform_to_string(stylesheet_file="test1.xsl")
681

    
682

    
683
            3) node = saxon_proc.parse_xml(xml_text="<in/>")\r
684
               result = xsltproc.transform_to_string(stylesheet_file="test1.xsl", xdm_node= node)
685
        """
686

    
687
        cdef char * c_sourcefile
688
        cdef char * c_stylesheetfile
689
        py_source_string = None
690
        py_stylesheet_string = None
691
        for key, value in kwds.items():
692
          if isinstance(value, str):
693
            if key == "source_file":
694
              py_source_string = value.encode('UTF-8') if value is not None else None
695
              if py_source_string  is None or isfile(py_source_string) == False:
696
                raise Exception("source file name does not exist")
697
              c_sourcefile = py_source_string if value is not None else "" 
698
            if key == "stylesheet_file":
699
              py_stylesheet_string = value.encode('UTF-8') if value is not None else None
700
              if py_stylesheet_string  is None or isfile(py_stylesheet_string) == False:
701
                raise Exception("Stylesheet file does not exist")
702
              c_stylesheetfile = py_stylesheet_string if value is not None else ""
703
          elif key == "xdm_node":
704
            if isinstance(value, PyXdmNode):
705
              self.setSourceFromXdmNode(value)
706
          elif len(kwds) > 0:
707
            raise Warning("Warning: transform_to_string should only the following keyword arguments: (source_file, stylesheet_file, xdm_node)")
708

    
709
        cdef const char* c_string            
710
        if len(kwds) == 0:
711
          c_string = self.thisxptr.transformToString()
712
        else:     
713
          c_string = self.thisxptr.transformFileToString(c_sourcefile if py_source_string is not None else NULL, c_stylesheetfile if py_stylesheet_string is not None else NULL)
714

    
715
        ustring = c_string.decode('UTF-8') if c_string is not NULL else None
716
        return ustring
717

    
718
     def transform_to_file(self, **kwds):
719
        """
720
        transform_to_file(self, **kwds)
721
        Execute transformation to a file. It is possible to specify the as an argument or using the set_output_file method.       
722
        Args:
723
            **kwds: Possible optional arguments: source_file (str) or xdm_node (PyXdmNode). Other allowed argument: stylesheet_file (str), output_file (str)
724

    
725

    
726
        Example:
727

    
728
            1) xsltproc.transform_to_file(source_file="cat.xml", stylesheet_file="test1.xsl", output_file="result.xml")
729

    
730
            2) xsltproc.set_source("cat.xml")\r
731
               xsltproc.setoutput_file("result.xml")\r
732
               xsltproc.transform_to_file(stylesheet_file="test1.xsl")
733

    
734

    
735
            3) node = saxon_proc.parse_xml(xml_text="<in/>")\r
736
               xsltproc.transform_to_file(output_file="result.xml", stylesheet_file="test1.xsl", xdm_node= node)        
737
        """
738
        cdef char * c_sourcefile
739
        cdef char * c_outputfile
740
        cdef char * c_stylesheetfile
741
        py_source_string = None
742
        py_stylesheet_string = None
743
        py_output_string = None
744
        cdef PyXdmNode node_
745
        for key, value in kwds.items():
746
          if isinstance(value, str):
747
            if key == "source_file":
748
              py_source_string = value.encode('UTF-8') if value is not None else None
749
              c_sourcefile = py_source_string if value is not None else ""
750
            if key == "output_file":
751
              py_output_string = value.encode('UTF-8') if value is not None else None
752
              c_outputfile = py_output_string if value is not None else ""  
753
            if key == "stylesheet_file":
754
              py_stylesheet_string = value.encode('UTF-8') if value is not None else None
755
              c_stylesheetfile = py_stylesheet_string if value is not None else ""
756
          elif key == "xdm_node":
757
            if isinstance(value, PyXdmNode):
758
              node_ = value
759
              self.thisxptr.setSourceFromXdmNode(node_.derivednptr)
760
            
761
        if len(kwds) == 0:
762
          self.thisxptr.transformToFile()
763
        else:     
764
          self.thisxptr.transformFileToFile(c_sourcefile if py_source_string is not None else NULL, c_stylesheetfile if py_stylesheet_string is not None else NULL, c_outputfile if py_output_string is not None else NULL)
765

    
766

    
767
     def transform_to_value(self, **kwds):
768
        """
769
        transform_to_value(self, **kwds)
770
        Execute transformation to an Xdm Node
771

    
772
        Args:
773
            **kwds: Possible optional arguments: source_file (str) or xdm_node (PyXdmNode). Other allowed argument: stylesheet_file (str)
774

    
775

    
776

    
777
        Returns:
778
            PyXdmNode: Result of the transformation as an PyXdmNode object
779

    
780

    
781
        Example:
782

    
783
            1) node = xsltproc.transform_to_value(source_file="cat.xml", stylesheet_file="test1.xsl")
784

    
785
            2) xsltproc.set_source("cat.xml")\r
786
               node = xsltproc.transform_to_value(stylesheet_file="test1.xsl")
787

    
788

    
789
            3) node = saxon_proc.parse_xml(xml_text="<in/>")\r
790
               node = xsltproc.transform_tovalue(stylesheet_file="test1.xsl", xdm_node= node)        
791
        """
792
        cdef const char * c_sourcefile = NULL
793
        cdef const char * c_stylesheetfile = NULL
794
        py_source_string = None
795
        py_stylesheet_string = None
796
        for key, value in kwds.items():
797
          if isinstance(value, str):
798
            if key == "source_file":
799
              c_sourcefile = make_c_str(value)  
800
            if key == "stylesheet_file":
801
              c_stylesheetfile = make_c_str(value)
802
          elif key == "xdm_node":
803
            if isinstance(value, PyXdmNode):
804
              self.setSourceFromXdmNode(value)
805
        cdef PyXdmValue val = None
806
        cdef PyXdmAtomicValue aval = None
807
        cdef PyXdmNode nval = None
808
        cdef saxoncClasses.XdmValue * xdmValue = NULL
809
        if len(kwds) == 0:
810
          xdmValue = self.thisxptr.transformToValue()
811
        else:     
812
          xdmValue = self.thisxptr.transformFileToValue(c_sourcefile, c_stylesheetfile)
813

    
814
        if xdmValue is NULL:
815
            return None        
816
        cdef type_ = xdmValue.getType()
817
        if type_== 4:
818
            aval = PyXdmAtomicValue()
819
            aval.derivedaptr = aval.derivedptr = aval.thisvptr = <saxoncClasses.XdmAtomicValue *>xdmValue
820
            return aval        
821
        elif type_ == 3:
822
            nval = PyXdmNode()        
823
            nval.derivednptr = nval.derivedptr = nval.thisvptr = <saxoncClasses.XdmNode*>xdmValue
824
            return nval
825
        else:
826
            val = PyXdmValue()
827
            val.thisvptr = xdmValue
828
            return val
829

    
830
     def compile_stylesheet(self, **kwds):
831
        """
832
        compile_stylesheet(self, **kwds)
833
        Compile a stylesheet  received as text, uri or as a node object. The compiled stylesheet is cached and available for execution
834
        later. It is also possible to save the compiled stylesheet (SEF file) given the option 'save' and 'output_file'
835
   
836
        Args:
837
            **kwds: Possible keyword arguments stylesheet_text (str), stylesheet_file (str) or stylsheetnode (PyXdmNode). Also possible
838
                    to add the options save (boolean), static_base_uri (str) and output_file (str), which creates an exported stylesheet to file (SEF).
839
                    The static_base_uri keyword argument can only be used with stylesheet_text. The base URI is part of the static context, and is used to
840
                    resolve any relative URIs appearing within an XPath expression.
841

    
842
        Example:
843
            1. xsltproc.compile_stylesheet(stylesheet_text="<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='2.0'>
844
            <xsl:param name='values' select='(2,3,4)' /><xsl:output method='xml' indent='yes' /><xsl:template match='*'><output>
845
              <xsl:value-of select='//person[1]'/>
846
              <xsl:for-each select='$values' >
847
                <out><xsl:value-of select='. * 3'/></out>
848
              </xsl:for-each></output></xsl:template>
849
            </xsl:stylesheet>")
850

    
851
            2. xsltproc.compile_stylesheet(stylesheet_file="test1.xsl", save=True, output_file="test1.sef")
852
        """
853
        py_error_message = "CompileStylesheet should only be one of the keyword option: (stylesheet_text|stylesheet_file|stylesheet_node), also allowed in addition the optional keyword 'save' boolean with the keyword 'outputfile' keyword"
854
        if len(kwds) >3:
855
          raise Exception(py_error_message)
856
        cdef char * c_outputfile
857
        cdef char * c_stylesheet
858
        py_output_string = None
859
        py_stylesheet_string = None
860
        py_save = False
861
        cdef int option = 0
862
        cdef PyXdmNode py_xdmNode = None
863
        if kwds.keys() >= {"stylesheet_text", "stylesheet_file"}:
864
          raise Exception(py_error_message)
865
        if kwds.keys() >= {"stylesheet_text", "stylesheet_node"}:
866
          raise Exception(py_error_message)
867
        if kwds.keys() >= {"stylesheet_node", "stylesheet_file"}:
868
          raise Exception(py_error_message)
869

    
870
        if ("save" in kwds) and kwds["save"]==True:
871
          del kwds["save"]
872
          if "output_file" not in kwds:
873
            raise Exception("Output file option not in keyword arugment for compile_stylesheet")
874
          py_output_string = kwds["output_file"].encode('UTF-8')
875
          c_outputfile = py_output_string
876
          if "stylesheet_text" in kwds:
877
            if "static_base_uri" in kwds:
878
              py_baseuri_string = kwds["static_base_uri"].encode('UTF-8')
879
              c_baseuri = py_baseuri_string
880
              self.thisxptr.setcwd(c_baseuri)
881
            py_stylesheet_string = kwds["stylesheet_text"].encode('UTF-8')
882
            c_stylesheet = py_stylesheet_string
883
            self.thisxptr.compileFromStringAndSave(c_stylesheet, c_outputfile)
884
          elif "stylesheet_file" in kwds:
885
            py_stylesheet_string = kwds["stylesheet_file"].encode('UTF-8')
886
            c_stylesheet = py_stylesheet_string
887
            self.thisxptr.compileFromFileAndSave(c_stylesheet, c_outputfile)
888
          elif "stylesheet_node" in kwds:
889
            py_xdmNode = kwds["stylesheet_node"]
890
            #if not isinstance(py_value, PyXdmNode):
891
              #raise Exception("StylesheetNode keyword arugment is not of type XdmNode")
892
            #value = PyXdmNode(py_value)
893
            self.thisxptr.compileFromXdmNodeAndSave(py_xdmNode.derivednptr, c_outputfile)
894
          else:
895
            raise Exception(py_error_message)
896
        else:
897
          if "stylesheet_text" in kwds:
898
            py_stylesheet_string = kwds["stylesheet_text"].encode('UTF-8')
899
            c_stylesheet = py_stylesheet_string
900
            if "static_base_uri" in kwds:
901
              py_baseuri_string = kwds["static_base_uri"].encode('UTF-8')
902
              c_baseuri = py_baseuri_string
903
              self.thisxptr.setcwd(c_baseuri)
904
            self.thisxptr.compileFromString(c_stylesheet)
905
          elif "stylesheet_file" in kwds:
906
            py_stylesheet_string = kwds["stylesheet_file"].encode('UTF-8')
907
            c_stylesheet = py_stylesheet_string
908
            self.thisxptr.compileFromFile(c_stylesheet)
909
          elif "stylesheet_node" in kwds:
910
            py_xdmNode = kwds["stylesheet_node"]
911
            #if not isinstance(py_value, PyXdmNode):
912
              #raise Exception("StylesheetNode keyword arugment is not of type XdmNode")
913
            #value = PyXdmNode(py_value)
914
            self.thisxptr.compileFromXdmNode(py_xdmNode.derivednptr)
915
          else:
916
            raise Exception(py_error_message)
917

    
918
     def release_stylesheet(self):
919
        """
920
        release_stylesheet(self)
921
        Release cached stylesheet
922

    
923
        """
924
        self.thisxptr.releaseStylesheet()
925

    
926
     def exception_occurred(self):
927
        """
928
        exception_occurred(self)
929
        Checks for pending exceptions without creating a local reference to the exception object
930
        Returns:
931
            boolean: True when there is a pending exception; otherwise return False        
932

    
933
        """
934
        return self.thisxptr.exceptionCount() >0
935

    
936
     def check_exception(self):
937
        """
938
        check_exception(self)
939
        Check for exception thrown and get message of the exception.
940
  
941
        Returns:
942
            str: Returns the exception message if thrown otherwise return None
943

    
944
        """
945
        cdef const char* c_string = self.thisxptr.checkException()
946
        ustring = c_string.decode('UTF-8') if c_string is not NULL else None
947
        return ustring
948

    
949
     def exception_clear(self):
950
        """
951
        exception_clear(self)
952
        Clear any exception thrown
953

    
954
        """
955
        self.thisxptr.exceptionClear()
956

    
957
     def exception_count(self):
958
        """
959
        excepton_count(self)
960
        Get number of errors reported during execution.
961

    
962
        Returns:
963
            int: Count of the exceptions thrown during execution
964
        """
965
        return self.thisxptr.exceptionCount()
966

    
967
     def get_error_message(self, index):
968
        """
969
        get_error_message(self, index)
970
        A transformation may have a number of errors reported against it. Get the ith error message if there are any errors
971

    
972
        Args:
973
            index (int): The i'th exception
974
        
975
        Returns:
976
            str: The message of the i'th exception. Return None if the i'th exception does not exist.
977
        """
978
        cdef const char* c_string = self.thisxptr.getErrorMessage(index)
979
        ustring = c_string.decode('UTF-8') if c_string is not NULL else None
980
        return ustring
981

    
982
     def get_error_code(self, index):
983
        """
984
        get_error_code(self, index)
985
        A transformation may have a number of errors reported against it. Get the i'th error code if there are any errors
986

    
987
        Args:
988
            index (int): The i'th exception
989
        
990
        Returns:
991
            str: The error code associated with the i'th exception. Return None if the i'th exception does not exist.
992

    
993
        """
994
        cdef const char* c_string = self.thisxptr.getErrorCode(index)
995
        ustring = c_string.decode('UTF-8') if c_string is not NULL else None
996
        return ustring
997

    
998
parametersDict = None
999

    
1000
cdef class PyXslt30Processor:
1001
     """An PyXslt30Processor represents factory to compile, load and execute a stylesheet.
1002
     It is possible to cache the context and the stylesheet in the PyXslt30Processor """
1003

    
1004
     cdef saxoncClasses.Xslt30Processor *thisxptr      # hold a C++ instance which we're wrapping
1005

    
1006

    
1007
     def __cinit__(self):
1008
        """Default constructor """
1009
        self.thisxptr = NULL
1010
     def __dealloc__(self):
1011
        if self.thisxptr != NULL:
1012
           del self.thisxptr
1013
     def set_cwd(self, cwd):
1014
        """
1015
        set_cwd(self, cwd)
1016
        Set the current working directory.
1017

    
1018
        Args:
1019
            cwd (str): current working directory
1020
        """
1021
        py_cwd_string = cwd.encode('UTF-8') if cwd is not None else None
1022
        cdef char * c_cwd = py_cwd_string if cwd is not None else ""
1023
        self.thisxptr.setcwd(c_cwd)
1024

    
1025
     def set_base_output_uri(self, base_uri):
1026
        """
1027
        set_base_output_uri(self, base_uri)
1028
        Set the base output URI. The default is the base URI of the principal output
1029
        of the transformation. If a base output URI is supplied using this function then it takes precedence
1030
        over any base URI defined in the principal output, and
1031
        it may cause the base URI of the principal output to be modified in situ.
1032
        The base output URI is used for resolving relative URIs in the 'href' attribute
1033
        of the xsl:result-document instruction; it is accessible to XSLT stylesheet
1034
        code using the XPath {@code current-output-uri()} function.
1035

    
1036
        Args:
1037
            base_uri (str): the base output URI
1038
        """
1039
        py_uri_string = base_uri.encode('UTF-8') if base_uri is not None else None
1040
        cdef char * c_uri = py_uri_string if base_uri is not None else ""
1041
        self.thisxptr.setBaseOutputURI(c_uri)
1042

    
1043
     def set_global_context_item(self, **kwds):
1044
        """Set the global context item for the transformation.
1045

    
1046
        Args:
1047
            **kwds: Keyword argument can only be one of the following: file_name|xdm_item
1048
        Raises:
1049
            Exception: Exception is raised if keyword argument is not one of file_name or an Xdm item.
1050
        """
1051

    
1052
        py_error_message = "Error: set_global_context_item should only contain one of the following keyword arguments: (file_name|xdm_item)"
1053
        if len(kwds) != 1:
1054
          raise Exception(py_error_message)
1055
        cdef py_value = None
1056
        cdef py_value_string = None
1057
        cdef char * c_source
1058
        cdef PyXdmItem xdm_item = None
1059
        if "file_name" in kwds:
1060
            py_value = kwds["file_name"]
1061
            py_value_string = py_value.encode('UTF-8') if py_value is not None else None
1062
            c_source = py_value_string if py_value is not None else ""
1063
            self.thisxptr.setGlobalContextFromFile(c_source)
1064
        elif "xdm_item" in kwds:
1065
            if isinstance(kwds["xdm_item"], PyXdmItem):
1066
                xdm_item = kwds["xdm_item"]
1067
                self.thisxptr.setGlobalContextItem(xdm_item.derivedptr)
1068
            else:
1069
                raise Exception("xdm_item value must be of type PyXdmItem")
1070
        else:
1071
          raise Exception(py_error_message)
1072

    
1073
     def set_initial_match_selection(self, **kwds):
1074
        """
1075
        set_initial_match_selection(self, **kwds)
1076
        The initial filename to which templates are to be applied (equivalent to the <code>select</code> attribute of <code>xsl:apply-templates</code>).
1077

    
1078
        Args:
1079
            **kwds: Keyword argument can only be one of the following: file_name|xdm_value
1080
        Raises:
1081
            Exception: Exception is raised if keyword argument is not one of file_name or XdmValue.
1082
        """
1083

    
1084
        py_error_message = "Error: set_initial_match_selection should only contain one of the following keyword arguments: (file_name|xdm_value)"
1085
        if len(kwds) != 1:
1086
          raise Exception(py_error_message)
1087
        cdef py_value = None
1088
        cdef py_value_string = None
1089
        cdef char * c_source
1090
        cdef PyXdmValue xdm_value = None
1091
        if "file_name" in kwds:
1092
            py_value = kwds["file_name"]
1093
            py_value_string = py_value.encode('UTF-8') if py_value is not None else None
1094
            c_source = py_value_string if py_value is not None else ""
1095
            self.thisxptr.setInitialMatchSelectionAsFile(c_source)
1096
        elif "xdm_value" in kwds:
1097
            xdm_value = kwds["xdm_value"]
1098
            self.thisxptr.setInitialMatchSelection(xdm_value.thisvptr)
1099
        else:
1100
          raise Exception(py_error_message)
1101

    
1102
     def set_output_file(self, output_file):
1103
        """
1104
        set_output_file(self, output_file)
1105
        Set the output file where the output of the transformation will be sent
1106

    
1107
        Args:
1108
            output_file (str): The output file supplied as a str
1109

    
1110
        """
1111
        py_filename_string = output_file.encode('UTF-8') if output_file is not None else None
1112
        cdef char * c_outputfile = py_filename_string if output_file is not None else ""
1113
        self.thisxptr.setOutputFile(c_outputfile)
1114

    
1115
     def set_jit_compilation(self, bool jit):
1116
        """
1117
        set_jit_compilation(self, jit)
1118
        Say whether just-in-time compilation of template rules should be used.
1119

    
1120
        Args:
1121
            jit (bool): True if just-in-time compilation is to be enabled. With this option enabled,
1122
                static analysis of a template rule is deferred until the first time that the
1123
                template is matched. This can improve performance when many template
1124
                rules are rarely used during the course of a particular transformation; however,
1125
                it means that static errors in the stylesheet will not necessarily cause the
1126
                compile(Source) method to throw an exception (errors in code that is
1127
                actually executed will still be notified but this may happen after the compile(Source)
1128
                method returns). This option is enabled by default in Saxon-EE, and is not available
1129
                in Saxon-HE or Saxon-PE.
1130
                Recommendation: disable this option unless you are confident that the
1131
                stylesheet you are compiling is error-free.
1132

    
1133
        """
1134
        cdef bool c_jit
1135
        c_jit = jit
1136
        self.thisxptr.setJustInTimeCompilation(c_jit)
1137
        #else:
1138
        #raise Warning("setJustInTimeCompilation: argument must be a boolean type. JIT not set")
1139

    
1140

    
1141
     def set_result_as_raw_value(self, bool is_raw):
1142
        """
1143
        set_result_as_raw_value(self, is_raw)
1144
        Set true if the return type of callTemplate, applyTemplates and transform methods is to return XdmValue, otherwise return XdmNode object with root Document node
1145

    
1146
        Args:
1147
            is_raw (bool): True if returning raw result, i.e. XdmValue, otherwise return XdmNode
1148

    
1149
        """
1150
        cdef bool c_raw
1151
        c_raw = is_raw
1152
        self.thisxptr.setResultAsRawValue(c_raw)
1153
        #else:
1154
        #raise Warning("setJustInTimeCompilation: argument must be a boolean type. JIT not set")
1155

    
1156
     def set_parameter(self, name, PyXdmValue value):
1157
        """
1158
        set_parameter(self, PyXdmValue value)
1159
        Set the value of a stylesheet parameter
1160

    
1161
        Args:
1162
            name (str): the name of the stylesheet parameter, as a string. For namespaced parameter use the JAXP solution i.e. "{uri}name
1163
            value (PyXdmValue): the value of the stylesheet parameter, or NULL to clear a previously set value
1164

    
1165
        """
1166
        cdef const char * c_str = make_c_str(name)
1167
        if c_str is not NULL:
1168
            '''value.thisvptr.incrementRefCount()
1169
            print("set_parameter called")'''
1170
            self.thisxptr.setParameter(c_str, value.thisvptr, False)
1171

    
1172
     def get_parameter(self, name):
1173
        """
1174
        get_parameter(self, name)
1175
        Get a parameter value by a given name
1176

    
1177
        Args:
1178
            name (str): The name of the stylesheet parameter
1179

    
1180
        Returns:
1181
            PyXdmValue: The Xdm value of the parameter
1182

    
1183

    
1184
        """
1185
        py_name_string = name.encode('UTF-8') if name is not None else None
1186
        cdef char * c_name = py_name_string if name is not None else ""
1187
        cdef PyXdmValue val = PyXdmValue()
1188
        val.thisvptr = self.thisxptr.getParameter(c_name)
1189
        return val
1190

    
1191
     def remove_parameter(self, name):
1192
        """
1193
        remove_parameter(self, name)
1194
        Remove the parameter given by name from the PyXslt30Processor. The parameter will not have any affect on the stylesheet if it has not yet been executed
1195

    
1196
        Args:
1197
            name (str): The name of the stylesheet parameter
1198

    
1199
        Returns:
1200
            bool: True if the removal of the parameter has been successful, False otherwise.
1201

    
1202
        """
1203

    
1204
        py_name_string = name.encode('UTF-8') if name is not None else None
1205
        cdef char * c_name = py_name_string if name is not None else ""
1206
        return self.thisxptr.removeParameter(c_name)
1207

    
1208
     def set_property(self, name, value):
1209
        """
1210
        set_property(self, name, value)
1211
        Set a property specific to the processor in use.
1212

    
1213
        Args:
1214
            name (str): The name of the property
1215
            value (str): The value of the property
1216

    
1217
        Example:
1218
            XsltProcessor: set serialization properties (names start with '!' i.e. name "!method" -> "xml")\r
1219
            'o':outfile name,\r
1220
            'it': initial template,\r
1221
            'im': initial mode,\r
1222
            's': source as file name\r
1223
            'm': switch on message listener for xsl:message instructions,\r
1224
            'item'| 'node' : source supplied as an XdmNode object,\r
1225
            'extc':Set the native library to use with Saxon for extension functions written in C/C++/PHP\r
1226

    
1227
        """
1228

    
1229
        py_name_string = name.encode('UTF-8') if name is not None else None
1230
        cdef char * c_name = py_name_string if name is not None else ""
1231
        py_value_string = value.encode('UTF-8') if value is not None else None
1232
        cdef char * c_value = py_value_string if value is not None else ""
1233
        self.thisxptr.setProperty(c_name, c_value)
1234

    
1235
     def clear_parameters(self):
1236
        """
1237
        clear_parameter(self)
1238
        Clear all parameters set on the processor for execution of the stylesheet
1239
        """
1240

    
1241
        self.thisxptr.clearParameters()
1242
     def clear_properties(self):
1243
        """
1244
        clear_properties(self)
1245
        Clear all properties set on the processor
1246
        """
1247

    
1248
        self.thisxptr.clearProperties()
1249

    
1250

    
1251
     def set_initial_template_parameters(self, bool tunnel, dict kwds):
1252
        """
1253
        set_initial_template_parameters(self, bool tunnel, **kwds)
1254
        Set parameters to be passed to the initial template. These are used
1255
        whether the transformation is invoked by applying templates to an initial source item,
1256
        or by invoking a named template. The parameters in question are the xsl:param elements
1257
        appearing as children of the xsl:template element.
1258

    
1259
        TODO: To fix issue where we pass XdmValue object created directly in the function argument. This causes seg error
1260
        e.g. set_initial_template_parameter(False, {a:saxonproc.make_integer_value(12)})
1261
        Do the following instead:
1262
        paramArr = {a:saxonproc.make_integer_value(12)}
1263
        set_initial_template_parameter(False, paramArr)
1264

    
1265
        Args:
1266
        	tunnel (bool): True if these values are to be used for setting tunnel parameters;
1267
        	**kwds: the parameters to be used for the initial template supplied as an key-value pair.
1268
        	False if they are to be used for non-tunnel parameters. The default is false.
1269

    
1270
        Example:
1271

    
1272
        	1)paramArr = {'a':saxonproc.make_integer_value(12), 'b':saxonproc.make_integer_value(5)} 
1273
                  xsltproc.set_initial_template_parameters(False, paramArr)
1274
        """
1275
        cdef map[string, saxoncClasses.XdmValue * ] parameters
1276
        cdef bool c_tunnel
1277
        cdef string key_str
1278
        c_tunnel = tunnel
1279
        cdef PyXdmAtomicValue value_
1280
        global parametersDict
1281
        if kwds is not None:
1282
                parametersDict = kwds
1283
        for (key, value) in kwds.items():
1284
                if isinstance(value, PyXdmAtomicValue):
1285
                        value_ = value
1286
                        key_str = key.encode('UTF-8')
1287
                        value_.derivedptr.incrementRefCount()
1288
                        parameters[key_str] = <saxoncClasses.XdmValue *> value_.derivedaptr
1289
                else:
1290
                        raise Exception("Initial template parameters can only be of type PyXdmValue")
1291
        if len(kwds) > 0:
1292
            self.thisxptr.setInitialTemplateParameters(parameters, c_tunnel);
1293

    
1294
     def setup_xsl_message(self, show, str file_name = None):
1295
        """
1296
        setup_xsl_message(self, **kwds)
1297
        gives users the option to switch on or off the <code>xsl:message</code> feature. It is also possible
1298
        to send the <code>xsl:message</code> outputs to file given by file name.
1299

    
1300
        """
1301
        py_name_string = file_name.encode('UTF-8') if file_name is not None else None
1302
        cdef char * c_file_name = py_name_string if file_name is not None else NULL
1303
        self.thisxptr.getXslMessages(show, c_file_name)
1304

    
1305
     def transform_to_string(self, **kwds):
1306
        """
1307
        transform_to_string(self, **kwds)
1308
        Execute transformation to string.
1309

    
1310
        Args:
1311
            **kwds: Possible arguments: source_file (str) or xdm_node (PyXdmNode). Other allowed argument: stylesheet_file (str)
1312
                                        and base_output_uri (str) which is used for for resolving relative URIs in the href
1313
                                        attribute of the xsl:result-document instruction.
1314

    
1315

    
1316
        Example:
1317

    
1318
            1) result = xsltproc.transform_to_string(source_file="cat.xml", stylesheet_file="test1.xsl")
1319

    
1320
            2) xsltproc.set_source("cat.xml")\r
1321
               result = xsltproc.transform_to_string(stylesheet_file="test1.xsl")
1322

    
1323

    
1324
            3) node = saxon_proc.parse_xml(xml_text="<in/>")\r
1325
               result = xsltproc.transform_to_string(stylesheet_file="test1.xsl", xdm_node= node)
1326
        """
1327

    
1328
        cdef char * c_sourcefile
1329
        cdef char * c_stylesheetfile
1330
        py_source_string = None
1331
        py_stylesheet_string = None
1332
        cdef PyXdmNode node_ = None
1333
        for key, value in kwds.items():
1334
          if isinstance(value, str):
1335
            if key == "source_file":
1336
              py_source_string = value.encode('UTF-8') if value is not None else None
1337
              c_sourcefile = py_source_string if value is not None else ""
1338
            if key == "base_output_uri":
1339
              c_base_output_uri = make_c_str(value)
1340
              self.thisxptr.setBaseOutputURI(c_base_output_uri)
1341
            if key == "stylesheet_file":
1342
              py_stylesheet_string = value.encode('UTF-8') if value is not None else None
1343
              c_stylesheetfile = py_stylesheet_string if value is not None else ""
1344
          elif key == "xdm_node":
1345
            if isinstance(value, PyXdmNode):
1346
              node_ = value
1347
          elif len(kwds) > 0:
1348
            raise Warning("Warning: transform_to_string should only contain the following keyword arguments: (source_file|xdm_node, stylesheet_file)")
1349

    
1350
        cdef const char* c_string
1351
        if node_ is not None:
1352
          if py_stylesheet_string is not None:
1353
            self.thisxptr.compileFromFile(c_stylesheetfile)
1354
          c_string = self.thisxptr.transformToString(node_.derivednptr)
1355
        else:
1356
          c_string = self.thisxptr.transformFileToString(c_sourcefile if py_source_string is not None else NULL, c_stylesheetfile if py_stylesheet_string is not None else NULL)
1357

    
1358
        ustring = c_string.decode('UTF-8') if c_string is not NULL else None
1359
        return ustring
1360

    
1361
     def transform_to_file(self, **kwds):
1362
        """
1363
        transform_to_file(self, **kwds)
1364
        Execute transformation to a file. It is possible to specify the as an argument or using the set_output_file method.
1365
        Args:
1366
            **kwds: Possible optional arguments: source_file (str) or xdm_node (PyXdmNode). Other allowed argument: stylesheet_file (str), output_file (str)
1367
                                                 and base_output_uri (str) which is used for for resolving relative URIs in the href attribute of the
1368
                                                 xsl:result-document instruction.
1369

    
1370
        Example:
1371

    
1372
            1) xsltproc.transform_to_file(source_file="cat.xml", stylesheet_file="test1.xsl", output_file="result.xml")
1373

    
1374
            2) xsltproc.set_source("cat.xml")\r
1375
               xsltproc.setoutput_file("result.xml")\r
1376
               xsltproc.transform_to_file(stylesheet_file="test1.xsl")
1377

    
1378

    
1379
            3) node = saxon_proc.parse_xml(xml_text="<in/>")\r
1380
               xsltproc.transform_to_file(output_file="result.xml", stylesheet_file="test1.xsl", xdm_node= node)
1381
        """
1382
        cdef char * c_sourcefile
1383
        cdef char * c_outputfile
1384
        cdef char * c_stylesheetfile
1385
        py_source_string = None
1386
        py_stylesheet_string = None
1387
        py_output_string = None
1388
        cdef PyXdmNode node_ = None
1389
        for key, value in kwds.items():
1390
                if isinstance(value, str):
1391
                        if key == "source_file":
1392
                                py_source_string = value.encode('UTF-8') if value is not None else None
1393
                                c_sourcefile = py_source_string if value is not None else ""
1394
                        if key == "base_output_uri":
1395
                                c_base_output_uri = make_c_str(value)
1396
                                self.thisxptr.setBaseOutputURI(c_base_output_uri)
1397
                        if key == "output_file":
1398
                                py_output_string = value.encode('UTF-8') if value is not None else None
1399
                                c_outputfile = py_output_string if value is not None else ""
1400
                        if key == "stylesheet_file":
1401
                                py_stylesheet_string = value.encode('UTF-8') if value is not None else None
1402
                                c_stylesheetfile = py_stylesheet_string if value is not None else ""
1403
                        elif key == "xdm_node":
1404
                                if isinstance(value, PyXdmNode):
1405
                                        node_ = value
1406
              
1407
        if node_ is not None:
1408
                if py_output_string is not None:
1409
                        self.thisxptr.setOutputFile(c_outputfile);
1410
                self.thisxptr.transformToFile(node_.derivednptr)
1411
        else:
1412
                self.thisxptr.transformFileToFile(c_sourcefile if py_source_string is not None else NULL, c_stylesheetfile if py_stylesheet_string is not None else NULL, c_outputfile if py_output_string is not None else NULL)
1413

    
1414

    
1415
     def transform_to_value(self, **kwds):
1416
        """
1417
        transform_to_value(self, **kwds)
1418
        Execute transformation to an Xdm Node
1419

    
1420
        Args:
1421
            **kwds: Possible optional arguments: source_file (str) or xdm_node (PyXdmNode). Other allowed argument: stylesheet_file (str)
1422
                                                 and base_output_uri (str) which is used for for resolving relative URIs in the href attribute
1423
                                                 of the xsl:result-document instruction.
1424

    
1425

    
1426

    
1427
        Returns:
1428
            PyXdmNode: Result of the transformation as an PyXdmNode object
1429

    
1430

    
1431
        Example:
1432

    
1433
            1) node = xsltproc.transform_to_value(source_file="cat.xml", stylesheet_file="test1.xsl")
1434

    
1435
            2) xsltproc.set_source("cat.xml")\r
1436
               node = xsltproc.transform_to_value(stylesheet_file="test1.xsl")
1437

    
1438

    
1439
            3) node = saxon_proc.parse_xml(xml_text="<in/>")\r
1440
               node = xsltproc.transform_tovalue(stylesheet_file="test1.xsl", xdm_node= node)
1441
        """
1442
        cdef const char * c_sourcefile = NULL
1443
        cdef const char * c_stylesheetfile = NULL
1444
        cdef PyXdmNode node_ = None
1445
        py_source_string = None
1446
        py_stylesheet_string = None
1447
        for key, value in kwds.items():
1448
          if isinstance(value, str):
1449
            if key == "source_file":
1450
              c_sourcefile = make_c_str(value)
1451
            if key == "base_output_uri":
1452
              c_base_output_uri = make_c_str(value)
1453
              self.thisxptr.setBaseOutputURI(c_base_output_uri)
1454
            if key == "stylesheet_file":
1455
              c_stylesheetfile = make_c_str(value)
1456
          elif key == "xdm_node":
1457
            if isinstance(value, PyXdmNode):
1458
              node_ = value
1459
        cdef PyXdmValue val = None
1460
        cdef PyXdmAtomicValue aval = None
1461
        cdef PyXdmNode nval = None
1462
        cdef saxoncClasses.XdmValue * xdmValue = NULL
1463
        if len(kwds) == 1 and node_ is not None:
1464
          xdmValue = self.thisxptr.transformToValue(node_.derivednptr)
1465
        else:
1466
          xdmValue = self.thisxptr.transformFileToValue(c_sourcefile, c_stylesheetfile)
1467

    
1468
        if xdmValue is NULL:
1469
            return None
1470
        cdef type_ = xdmValue.getType()
1471
        if type_== 4:
1472
            aval = PyXdmAtomicValue()
1473
            aval.derivedaptr = aval.derivedptr = aval.thisvptr = <saxoncClasses.XdmAtomicValue *>xdmValue
1474
            return aval
1475
        elif type_ == 3:
1476
            nval = PyXdmNode()
1477
            nval.derivednptr = nval.derivedptr = nval.thisvptr = <saxoncClasses.XdmNode*>xdmValue
1478
            return nval
1479
        else:
1480
            val = PyXdmValue()
1481
            val.thisvptr = xdmValue
1482
            return val
1483

    
1484
     def apply_templates_returning_value(self, **kwds):
1485
        """
1486
        apply_templates_returning_value(self, **kwds)
1487
        Invoke the stylesheet by applying templates to a supplied input sequence, Saving the results as an XdmValue.
1488

    
1489
        Args:
1490
            **kwds: Possible optional arguments: source_file (str) or xdm_value (PyXdmValue). Other allowed argument: stylesheet_file (str) and
1491
                                                 base_output_uri (str) which is used for for resolving relative URIs in the href attribute of
1492
                                                 the xsl:result-document instruction.
1493

    
1494

    
1495

    
1496
        Returns:
1497
            PyXdmValue: Result of the transformation as an PyXdmValue object
1498

    
1499

    
1500
        Example:
1501

    
1502
            1) xsltproc.set_initial_match_selection(file_name="cat.xml")\r
1503
               node = xsltproc.apply_templates_returning_value(stylesheet_file="test1.xsl")
1504

    
1505

    
1506
            2) xsltproc.compile_stylesheet(stylesheet_file="test1.xsl")
1507
			   xsltproc.set_initial_match_selection(file_name="cat.xml")\r
1508
               node = xsltproc.apply_templates_returning_value()
1509

    
1510
        """
1511
        cdef const char * c_sourcefile = NULL
1512
        cdef const char * c_stylesheetfile = NULL
1513
        cdef PyXdmValue value_ = None
1514
        py_source_string = None
1515
        py_stylesheet_string = None
1516
        for key, value in kwds.items():
1517
          if isinstance(value, str):
1518
            if key == "source_file":
1519
              c_sourcefile = make_c_str(value)
1520
              self.thisxptr.setInitialMatchSelectionAsFile(c_sourcefile)
1521
            if key == "base_output_uri":
1522
              c_base_output_uri = make_c_str(value)
1523
              self.thisxptr.setBaseOutputURI(c_base_output_uri)
1524
            if key == "stylesheet_file":
1525
              c_stylesheetfile = make_c_str(value)
1526
          elif key == "xdm_value":
1527
            if isinstance(value, PyXdmValue):
1528
              value_ = value;
1529
              self.thisxptr.setInitialMatchSelection(value_.thisvptr)
1530
        cdef PyXdmValue val = None
1531
        cdef PyXdmAtomicValue aval = None
1532
        cdef PyXdmNode nval = None
1533
        cdef saxoncClasses.XdmValue * xdmValue = NULL
1534
        xdmValue = self.thisxptr.applyTemplatesReturningValue(c_stylesheetfile)
1535

    
1536
        if xdmValue is NULL:
1537
            return None
1538
        cdef type_ = xdmValue.getType()
1539
        if type_== 4:
1540
            aval = PyXdmAtomicValue()
1541
            aval.derivedaptr = aval.derivedptr = aval.thisvptr = <saxoncClasses.XdmAtomicValue *>xdmValue
1542
            return aval
1543
        elif type_ == 3:
1544
            nval = PyXdmNode()
1545
            nval.derivednptr = nval.derivedptr = nval.thisvptr = <saxoncClasses.XdmNode*>xdmValue
1546
            return nval
1547
        else:
1548
            val = PyXdmValue()
1549
            val.thisvptr = xdmValue
1550
            return val
1551

    
1552

    
1553
     def apply_templates_returning_string(self, **kwds):
1554
        """
1555
        apply_templates_returning_string(self, **kwds)
1556
        Invoke the stylesheet by applying templates to a supplied input sequence, Saving the results as a str.
1557

    
1558
        Args:
1559
            **kwds: Possible optional arguments: source_file (str) or xdm_value (PyXdmValue). Other allowed argument: stylesheet_file (str) and
1560
                                                 base_output_uri (str) which is used for for resolving relative URIs in the href attribute of
1561
                                                 the xsl:result-document instruction
1562

    
1563

    
1564

    
1565
        Returns:
1566
            PyXdmValue: Result of the transformation as an PyXdmValue object
1567

    
1568

    
1569
        Example:
1570

    
1571
            1) xsltproc.set_initial_match_selection(file_name="cat.xml")\r
1572
               content = xsltproc.apply_templates_returning_str(stylesheet_file="test1.xsl")
1573
			   print(content)
1574

    
1575
        """
1576
        cdef const char * c_sourcefile = NULL
1577
        cdef const char * c_stylesheetfile = NULL
1578
        cdef PyXdmValue value_ = None
1579
        py_source_string = None
1580
        py_stylesheet_string = None
1581
        for key, value in kwds.items():
1582
          if isinstance(value, str):
1583
            if key == "source_file":
1584
              c_sourcefile = make_c_str(value)
1585
              self.thisxptr.setInitialMatchSelectionAsFile(c_sourcefile)
1586
            if key == "base_output_uri":
1587
              c_base_output_uri = make_c_str(value)
1588
              self.thisxptr.setBaseOutputURI(c_base_output_uri)
1589
            if key == "stylesheet_file":
1590
              c_stylesheetfile = make_c_str(value)
1591
          elif key == "xdm_value":
1592
            if isinstance(value, PyXdmValue):
1593
              value_ = value;
1594
              self.thisxptr.setInitialMatchSelection(value_.thisvptr)
1595
        cdef const char* c_string  = self.thisxptr.applyTemplatesReturningString(c_stylesheetfile) 
1596
        ustring = c_string.decode('UTF-8') if c_string is not NULL else None
1597
        return ustring
1598

    
1599
     def apply_templates_returning_file(self, **kwds):
1600
        """
1601
        apply_templates_returning_file(self, **kwds)
1602
        Invoke the stylesheet by applying templates to a supplied input sequence, Saving the 
1603
        results to file.
1604

    
1605
        Args:
1606
            **kwds: Possible optional arguments: source_file (str) or xdm_value (PyXdmValue). 
1607
            Other allowed argument: stylesheet_file (str) and the required argument output_file (str),
1608
            base_output_uri (str) which is used for for resolving relative URIs in the href attribute of
1609
            the xsl:result-document instruction.
1610

    
1611

    
1612
        Returns:
1613
            PyXdmValue: Result of the transformation as an PyXdmValue object
1614

    
1615

    
1616
        Example:
1617

    
1618
            1) xsltproc.set_initial_match_selection(file_name="cat.xml")\r
1619
               content = xsltproc.apply_templates_returning_file(stylesheet_file="test1.xsl", output_file="result.xml")
1620
			   print(content)
1621

    
1622
        """
1623
        cdef const char * c_sourcefile = NULL
1624
        cdef const char * c_stylesheetfile = NULL
1625
        cdef const char * c_outputfile = NULL
1626
        cdef PyXdmValue value_ = None
1627
        py_source_string = None
1628
        py_stylesheet_string = None
1629
        py_output_string = None
1630
        for key, value in kwds.items():
1631
          if isinstance(value, str):
1632
            if key == "source_file":
1633
              c_sourcefile = make_c_str(value)
1634
              self.thisxptr.setInitialMatchSelectionAsFile(c_sourcefile)
1635
            if key == "base_output_uri":
1636
              c_base_output_uri = make_c_str(value)
1637
              self.thisxptr.setBaseOutputURI(c_base_output_uri)
1638
            if key == "output_file":
1639
              py_output_string = value.encode('UTF-8') if value is not None else None
1640
              c_outputfile = py_output_string if value is not None else ""
1641
            if key == "stylesheet_file":
1642
              c_stylesheetfile = make_c_str(value)
1643
          elif key == "xdm_value":
1644
            if isinstance(value, PyXdmNode):
1645
              value_ = value;
1646
              self.thisxptr.setInitialMatchSelection(value_.thisvptr)
1647
        self.thisxptr.applyTemplatesReturningFile(c_stylesheetfile, c_outputfile) 
1648
        
1649

    
1650
     def call_template_returning_value(self, str template_name=None, **kwds):
1651
        """
1652
        call_template_returning_value(self, str template_name, **kwds)
1653
        Invoke a transformation by calling a named template and return result as an PyXdmValue.
1654

    
1655
        Args:
1656
			template_name(str): The name of the template to invoke. If None is supplied then call the initial-template
1657
            **kwds: Possible optional arguments: source_file (str) or xdm_value (PyXdmValue). Other allowed argument: stylesheet_file (str),
1658
                    base_output_uri (str) which is used for for resolving relative URIs in the href attribute of the xsl:result-document instruction
1659

    
1660

    
1661
        Returns:
1662
            PyXdmValue: Result of the transformation as an PyXdmValue object
1663

    
1664

    
1665
        Example:
1666
            1) node = xsltproc.call_template_returning_value("main", stylesheet_file="test1.xsl")
1667

    
1668

    
1669
            2) xsltproc.set_initial_match_selection(file_name="cat.xml")\r
1670
               node = xsltproc.call_template_returning_value("main", stylesheet_file="test1.xsl")
1671

    
1672

    
1673
            3) xsltproc.compile_stylesheet(stylesheet_file="test2.xsl")
1674
			   xsltproc.set_initial_match_selection(file_name="cat.xml")\r
1675
               node = xsltproc.call_template_returning_value("go")
1676

    
1677
        """
1678
        cdef const char * c_templateName = NULL
1679
        cdef const char * c_sourcefile = NULL
1680
        cdef const char * c_stylesheetfile = NULL
1681
        cdef PyXdmValue value_ = None
1682
        py_source_string = None
1683
        py_template_name_str = None
1684
        py_stylesheet_string = None
1685
        for key, value in kwds.items():
1686
          if isinstance(value, str):
1687
            if key == "source_file":
1688
              c_sourcefile = make_c_str(value)
1689
              self.thisxptr.setInitialMatchSelectionAsFile(c_sourcefile)
1690
            if key == "base_output_uri":
1691
              c_base_output_uri = make_c_str(value)
1692
              self.thisxptr.setBaseOutputURI(c_base_output_uri)
1693
            if key == "stylesheet_file":
1694
              c_stylesheetfile = make_c_str(value)
1695
          elif key == "xdm_node":
1696
            if isinstance(value, PyXdmValue):
1697
              value_ = value;
1698
              self.thisxptr.setInitialMatchSelection(value_.thisvptr)
1699

    
1700
        c_templateName = make_c_str(template_name)
1701
        cdef PyXdmValue val = None
1702
        cdef PyXdmAtomicValue aval = None
1703
        cdef PyXdmNode nval = None
1704
        cdef saxoncClasses.XdmValue * xdmValue = NULL
1705
        xdmValue = self.thisxptr.callTemplateReturningValue(c_stylesheetfile, c_templateName)
1706

    
1707
        if xdmValue is NULL:
1708
            return None
1709
        cdef type_ = xdmValue.getType()
1710
        if type_== 4:
1711
            aval = PyXdmAtomicValue()
1712
            aval.derivedaptr = aval.derivedptr = aval.thisvptr = <saxoncClasses.XdmAtomicValue *>xdmValue
1713
            return aval
1714
        elif type_ == 3:
1715
            nval = PyXdmNode()
1716
            nval.derivednptr = nval.derivedptr = nval.thisvptr = <saxoncClasses.XdmNode*>xdmValue
1717
            return nval
1718
        else:
1719
            val = PyXdmValue()
1720
            val.thisvptr = xdmValue
1721
            return val
1722

    
1723

    
1724

    
1725
     def call_template_returning_string(self, str template_name=None, **kwds):
1726
        """
1727
        call_template_returning_string(self, str template_name, **kwds)
1728
        Invoke a transformation by calling a named template and return result as a string.
1729

    
1730
        Args:
1731
			template_name(str): The name of the template to invoke. If None is supplied then call the initial-template
1732
            **kwds: Possible optional arguments: source_file (str) or  xdm_Value (PyXdmValue). Other allowed argument: stylesheet_file (str)
1733
            base_output_uri (str) which is used for for resolving relative URIs in the href attribute of the xsl:result-document instruction
1734

    
1735

    
1736

    
1737
        Returns:
1738
            PyXdmValue: Result of the transformation as an PyXdmValue object
1739

    
1740

    
1741
        Example:
1742
            1) result = xsltproc.call_template_returning_string("main", stylesheet_file="test1.xsl")
1743

    
1744

    
1745
            2) xsltproc.set_initial_match_selection(file_name="cat.xml")\r
1746
               result = xsltproc.call_template_returning_string("main", stylesheet_file="test1.xsl")
1747

    
1748
        cdef const char * c_templateName = NULL
1749

    
1750
            3) xsltproc.compile_stylesheet(stylesheet_file="test2.xsl")
1751
			   xsltproc.set_initial_match_selection(file_name="cat.xml")\r
1752
               result = xsltproc.call_template_returning_string("go")
1753
			   print(result)
1754
        """
1755
        cdef const char * c_sourcefile = NULL
1756
        cdef const char * c_stylesheetfile = NULL
1757
        cdef PyXdmNode value_ = None
1758
        py_source_string = None
1759
        py_template_name_str = None
1760
        py_stylesheet_string = None
1761
        for key, value in kwds.items():
1762
          if isinstance(value, str):
1763
            if key == "source_file":
1764
              c_sourcefile = make_c_str(value)
1765
              self.thisxptr.setInitialMatchSelectionAsFile(c_sourcefile)
1766
            if key == "base_output_uri":
1767
              c_base_output_uri = make_c_str(value)
1768
              self.thisxptr.setBaseOutputURI(c_base_output_uri)
1769
            if key == "stylesheet_file":
1770
              c_stylesheetfile = make_c_str(value)
1771
          elif key == "xdm_value":
1772
            if isinstance(value, PyXdmValue):
1773
              value_ = value;
1774
              self.thisxptr.setInitialMatchSelection(value_.thisvptr)
1775

    
1776
        c_templateName = make_c_str(template_name)
1777
        cdef const char* c_string  = self.thisxptr.callTemplateReturningString(c_stylesheetfile, c_templateName) 
1778
        ustring = c_string.decode('UTF-8') if c_string is not NULL else None
1779
        return ustring
1780

    
1781

    
1782
     def call_template_returning_file(self, str template_name=None, **kwds):
1783
        """
1784
        call_template_returning_file(self, str template_name, **kwds)
1785
        Invoke a transformation by calling a named template and save result in a specified file.
1786

    
1787
        Args:
1788
			template_name(str): The name of the template to invoke. If None is supplied then call the initial-template
1789
            **kwds: Possible optional arguments: source_file (str) or xdm_node (PyXdmNode). Other allowed argument: stylesheet_file (str)
1790
                    base_output_uri (str) which is used for for resolving relative URIs in the href attribute of the xsl:result-document instruction
1791

    
1792

    
1793
        Returns:
1794
            PyXdmValue: Result of the transformation as an PyXdmValue object
1795

    
1796

    
1797
        Example:
1798
            1) xsltproc.call_template_returning_file("main", stylesheet_file="test1.xsl",  output_file="result.xml")
1799

    
1800

    
1801
            2) xsltproc.set_initial_match_selection(file_name="cat.xml")\r
1802
               xsltproc.call_template_returning_file("main", stylesheet_file="test1.xsl", output_file="result.xml")
1803

    
1804

    
1805
            3) xsltproc.compile_stylesheet(stylesheet_file="test2.xsl")
1806
			   xsltproc.set_initial_match_selection(file_name="cat.xml")\r
1807
               xsltproc.call_template_returning_file("go", output_file="result.xml")
1808
			   print(result)
1809
        """
1810
        cdef char * c_outputfile = NULL
1811
        cdef const char * c_templateName = NULL
1812
        cdef const char * c_sourcefile = NULL
1813
        cdef const char * c_stylesheetfile = NULL
1814
        cdef PyXdmValue value_ = None
1815
        py_source_string = None
1816
        py_template_name_str = None
1817
        py_stylesheet_string = None
1818
        py_output_string = None
1819
        for key, value in kwds.items():
1820
          if isinstance(value, str):
1821
            if key == "source_file":
1822
              c_sourcefile = make_c_str(value)
1823
              self.thisxptr.setInitialMatchSelectionAsFile(c_sourcefile)
1824
            if key == "base_output_uri":
1825
              c_base_output_uri = make_c_str(value)
1826
              self.thisxptr.setBaseOutputURI(c_base_output_uri)
1827
            if key == "output_file":
1828
              py_output_string = value.encode('UTF-8') if value is not None else None
1829
              c_outputfile = py_output_string if value is not None else ""
1830
            if key == "stylesheet_file":
1831
              c_stylesheetfile = make_c_str(value)
1832
          elif key == "xdm_value":
1833
            if isinstance(value, PyXdmValue):
1834
              value_ = value;
1835
              self.thisxptr.setInitialMatchSelection(value_.thisvptr)
1836

    
1837
        c_templateName = make_c_str(template_name)
1838
        self.thisxptr.callTemplateReturningFile(c_stylesheetfile, c_templateName, c_outputfile)
1839

    
1840

    
1841

    
1842
     def call_function_returning_value(self, str function_name, list args, **kwds):
1843
        """
1844
        call_function_returning_value(self, str function_name, list args, **kwds)
1845
        Invoke a transformation by calling a named template and return result as an PyXdmValue.
1846

    
1847
        Args:
1848
			function_name(str): The name of the template to invoke. If None is supplied then call the initial-template
1849
			list args: Pointer array of XdmValue object - he values of the arguments to be supplied to the function.
1850
            **kwds: Possible optional arguments: source_file (str) or xdm_value (PyXdmValue). Other allowed argument: stylesheet_file (str)
1851

    
1852

    
1853

    
1854
        Returns:
1855
            PyXdmValue: Result of the transformation as an PyXdmValue object
1856

    
1857

    
1858
        Example:
1859
            1) node = xsltproc.call_function_returning_value("{http://localhost/example}func", stylesheet_file="test1.xsl")
1860

    
1861

    
1862
            2) xsltproc.set_initial_match_selection(file_name="cat.xml")\r
1863
               value = xsltproc.call_function_returning_value("{http://localhost/test}add", stylesheet_file="test1.xsl")
1864

    
1865

    
1866
            3) xsltproc.compile_stylesheet(stylesheet_file="test2.xsl")
1867
			   xsltproc.set_initial_match_selection(file_name="cat.xml")\r
1868
               value = xsltproc.call_function_returning_value("{http://exmaple.com}func1")
1869

    
1870
        """
1871
        cdef const char * c_functionName = NULL
1872
        cdef const char * c_sourcefile = NULL
1873
        cdef const char * c_stylesheetfile = NULL
1874
        cdef PyXdmValue value_ = None
1875
        py_source_string = None
1876
        py_template_name_str = None
1877
        py_stylesheet_string = None
1878
        for key, value in kwds.items():
1879
          if isinstance(value, str):
1880
            if key == "source_file":
1881
              c_sourcefile = make_c_str(value)
1882
              self.thisxptr.setInitialMatchSelectionAsFile(c_sourcefile)
1883
            if key == "stylesheet_file":
1884
              c_stylesheetfile = make_c_str(value)
1885
          elif key == "xdm_value":
1886
            if isinstance(value, PyXdmValue):
1887
              value_ = value;
1888
              self.thisxptr.setInitialMatchSelection(value_.thisvptr)
1889
        cdef int len_= 0;
1890
        len_ = len(args)
1891
        """ TODO handle memory when finished with XdmValues """
1892
        cdef saxoncClasses.XdmValue ** argumentV = self.thisxptr.createXdmValueArray(len_)
1893
        
1894
        for x in range(len(args)):
1895
          if isinstance(args[x], PyXdmValue):
1896
            value_ = args[x];
1897
            argumentV[x] = value_.thisvptr
1898
          else:
1899
            raise Exception("Argument value at position " , x , " is not an PyXdmValue. The following object found: ", type(args[x]))
1900

    
1901
        c_functionName = make_c_str(function_name)
1902
        cdef PyXdmValue val = None
1903
        cdef PyXdmAtomicValue aval = None
1904
        cdef PyXdmNode nval = None
1905
        cdef saxoncClasses.XdmValue * xdmValue = NULL
1906
        xdmValue = self.thisxptr.callFunctionReturningValue(c_stylesheetfile, c_functionName, argumentV, len(args))
1907

    
1908
        if xdmValue is NULL:
1909
          return None
1910
        cdef type_ = xdmValue.getType()
1911
        if type_== 4:
1912
          aval = PyXdmAtomicValue()
1913
          aval.derivedaptr = aval.derivedptr = aval.thisvptr = <saxoncClasses.XdmAtomicValue *>xdmValue
1914
          return aval
1915
        elif type_ == 3:
1916
          nval = PyXdmNode()
1917
          nval.derivednptr = nval.derivedptr = nval.thisvptr = <saxoncClasses.XdmNode*>xdmValue
1918
          return nval
1919
        else:
1920
          val = PyXdmValue()
1921
          val.thisvptr = xdmValue
1922
          return val
1923

    
1924

    
1925

    
1926
     def call_function_returning_string(self, str function_name, list args, **kwds):
1927
        """
1928
        call_function_returning_string(self, str function_name, list args, **kwds)
1929
        Invoke a transformation by calling a named template and return result as a serialized string.
1930

    
1931
        Args:
1932
			function_name(str): The name of the template to invoke. If None is supplied then call the initial-template
1933
			list args: Pointer array of XdmValue object - he values of the arguments to be supplied to the function.
1934
            **kwds: Possible optional arguments: source_file (str) or xdm_value (PyXdmValue). Other allowed argument: stylesheet_file (str)
1935

    
1936

    
1937

    
1938
        Returns:
1939
            str: Result of the transformation as an str value
1940

    
1941

    
1942
        Example:
1943
            1) result = xsltproc.call_function_returning_string("{http://localhost/example}func", stylesheet_file="test1.xsl")
1944

    
1945

    
1946
            2) xsltproc.set_initial_match_selection(file_name="cat.xml")\r
1947
               result = xsltproc.call_function_returning_string("{http://localhost/test}add", stylesheet_file="test1.xsl")
1948

    
1949

    
1950
            3) xsltproc.compile_stylesheet(stylesheet_file="test2.xsl")
1951
			   xsltproc.set_initial_match_selection(file_name="cat.xml")\r
1952
               result = xsltproc.call_function_returning_string("{http://exmaple.com}func1")
1953

    
1954
        """
1955
        cdef const char * c_functionName = NULL
1956
        cdef const char * c_sourcefile = NULL
1957
        cdef const char * c_stylesheetfile = NULL
1958
        cdef PyXdmValue value_ = None
1959
        py_source_string = None
1960
        py_template_name_str = None
1961
        py_stylesheet_string = None
1962
        for key, value in kwds.items():
1963
          if isinstance(value, str):
1964
            if key == "source_file":
1965
              c_sourcefile = make_c_str(value)
1966
              self.thisxptr.setInitialMatchSelectionAsFile(c_sourcefile)
1967
            if key == "base_output_uri":
1968
              c_base_output_uri = make_c_str(value)
1969
              self.thisxptr.setBaseOutputURI(c_base_output_uri)
1970
            if key == "stylesheet_file":
1971
              c_stylesheetfile = make_c_str(value)
1972
              if isfile(value) == False:
1973
                raise Exception("Stylesheet file does not exist")
1974
          elif key == "xdm_value":
1975
            if isinstance(value, PyXdmValue):
1976
              value_ = value;
1977
              self.thisxptr.setInitialMatchSelection(value_.thisvptr)
1978
        cdef int _len = len(args)
1979
        """ TODO handle memory when finished with XdmValues """
1980
        cdef saxoncClasses.XdmValue ** argumentV = self.thisxptr.createXdmValueArray(_len)
1981

    
1982
        for x in range(len(args)):
1983
          if isinstance(args[x], PyXdmValue):
1984
            value_ = args[x]
1985
            argumentV[x] = value_.thisvptr
1986
          else:
1987
            raise Exception("Argument value at position ",x," is not an PyXdmValue")
1988

    
1989
        c_functionName = make_c_str(function_name)
1990
        cdef PyXdmValue val = None
1991
        cdef PyXdmAtomicValue aval = None
1992
        cdef PyXdmNode nval = None
1993
        cdef saxoncClasses.XdmValue * xdmValue = NULL
1994
        cdef const char* c_string = self.thisxptr.callFunctionReturningString(c_stylesheetfile, c_functionName, argumentV, len(args))
1995
        ustring = c_string.decode('UTF-8') if c_string is not NULL else None
1996
        return ustring
1997

    
1998

    
1999
     def call_function_returning_file(self, str function_name, list args, **kwds):
2000
        """
2001
        call_function_returning_file(self, str function_name, list args, **kwds)
2002
        Invoke a transformation by calling a named template and return result as an PyXdmValue.
2003

    
2004
        Args:
2005
			function_name(str): The name of the template to invoke. If None is supplied 
2006
                        then call the initial-template
2007
			list args: Pointer array of XdmValue object - he values of the arguments to be supplied to the function.
2008
            **kwds: Possible optional arguments: source_file (str) or xdm_value (PyXdmValue). Other allowed argument: stylesheet_file (str)
2009

    
2010

    
2011

    
2012
        Returns:
2013
            PyXdmValue: Result of the transformation as an PyXdmValue object
2014

    
2015

    
2016
        Example:
2017
            1)  xsltproc.set_output_file("result.xml")
2018
				xsltproc.call_function_returning_file("{http://localhost/example}func", stylesheet_file="test1.xsl")
2019

    
2020

    
2021
            2) xsltproc.set_initial_match_selection(file_name="cat.xml")\r
2022
               xsltproc.call_function_returning_file("{http://localhost/test}add", stylesheet_file="test1.xsl", output_file="result.xml")
2023

    
2024

    
2025
            3) xsltproc.compile_stylesheet(stylesheet_file="test2.xsl")
2026
			   xsltproc.set_initial_match_selection(file_name="cat.xml")\r
2027
               xsltproc.call_function_returning_file("{http://exmaple.com}func1", output_file="result.xml")
2028

    
2029
        """
2030
        cdef const char * c_functionName = NULL
2031
        cdef const char * c_sourcefile = NULL
2032
        cdef const char * c_outputfile = NULL
2033
        cdef const char * c_stylesheetfile = NULL
2034
        cdef PyXdmValue value_ = None
2035
        cdef PyXdmValue valueArgs_ = None
2036
        py_source_string = None
2037
        py_template_name_str = None
2038
        py_stylesheet_string = None
2039
        for key, value in kwds.items():
2040
          if isinstance(value, str):
2041
            if key == "source_file":
2042
              c_sourcefile = make_c_str(value)
2043
              self.thisxptr.setInitialMatchSelectionAsFile(c_sourcefile)
2044
            if key == "base_output_uri":
2045
              c_base_output_uri = make_c_str(value)
2046
              self.thisxptr.setBaseOutputURI(c_base_output_uri)
2047
            if key == "output_file":
2048
              py_output_string = value.encode('UTF-8') if value is not None else None
2049
              c_outputfile = py_output_string if value is not None else ""
2050
            if key == "stylesheet_file":
2051
              c_stylesheetfile = make_c_str(value)
2052
              if isfile(value) == False:
2053
                raise Exception("Stylesheet file does not exist")
2054
          elif key == "xdm_value":
2055
            if isinstance(value, PyXdmValue):
2056
              value_ = value;
2057
              self.thisxptr.setInitialMatchSelection(value_.thisvptr)
2058
        cdef int _len = len(args)
2059
        """ TODO handle memory when finished with XdmValues """
2060
        cdef saxoncClasses.XdmValue ** argumentV = self.thisxptr.createXdmValueArray(_len)
2061

    
2062
        for x in range(len(args)):
2063
          if isinstance(args[x], PyXdmValue):
2064
            value_ = args[x]
2065
            argumentV[x] = value_.thisvptr
2066
          else:
2067
            raise Exception("Argument value at position ",x," is not an PyXdmValue")
2068

    
2069
        c_functionName = make_c_str(function_name)
2070
        cdef PyXdmValue val = None
2071
        cdef PyXdmAtomicValue aval = None
2072
        cdef PyXdmNode nval = None
2073
        cdef saxoncClasses.XdmValue * xdmValue = NULL
2074
        self.thisxptr.callFunctionReturningFile(c_stylesheetfile, c_functionName, argumentV, len(args), c_outputfile)
2075
	
2076

    
2077
        
2078
     def compile_stylesheet(self, **kwds):
2079
        """
2080
        compile_stylesheet(self, **kwds)
2081
        Compile a stylesheet  received as text, uri or as a node object. The compiled stylesheet 
2082
        is cached and available for execution later. It is also possible to save the compiled 
2083
        stylesheet (SEF file) given the option 'save' and 'output_file'.
2084

    
2085
        Get the stylesheet associated via the xml-stylesheet processing instruction (see
2086
        http://www.w3.org/TR/xml-stylesheet/) with the document
2087
        document specified in the source parameter, and that match
2088
        the given criteria.  If there are several suitable xml-stylesheet
2089
        processing instructions, then the returned Source will identify
2090
        a synthesized stylesheet module that imports all the referenced
2091
        stylesheet module.
2092

    
2093
        Args:
2094
            **kwds: Possible keyword arguments stylesheet_text (str), stylesheet_file (str), 
2095
            associated_file (str) or stylsheet_node (PyXdmNode). Also possible to add the options 
2096
            save (boolean) and output_file, which creates an exported stylesheet to file (SEF).
2097

    
2098
        Example:
2099
            1. xsltproc.compile_stylesheet(stylesheet_text="<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='2.0'>
2100
                                             <xsl:param name='values' select='(2,3,4)' /><xsl:output method='xml' indent='yes' />
2101
                                             <xsl:template match='*'><output><xsl:value-of select='//person[1]'/>
2102
                                             <xsl:for-each select='$values' >
2103
                                               <out><xsl:value-of select='. * 3'/></out>
2104
                                             </xsl:for-each></output></xsl:template></xsl:stylesheet>")
2105

    
2106
            2. xsltproc.compile_stylesheet(stylesheet_file="test1.xsl", save=True, output_file="test1.sef")
2107
            3. xsltproc.compile(associated_file="foo.xml")  
2108
        """
2109
        py_error_message = "CompileStylesheet should only be one of the keyword option: (associated_file|stylesheet_text|stylesheet_file|stylesheet_node), also in allowed in addition the optional keyword 'save' boolean with the keyword 'outputfile' keyword"
2110
        if len(kwds) >3:
2111
          raise Exception(py_error_message)
2112
        cdef char * c_outputfile
2113
        cdef char * c_stylesheet
2114
        py_output_string = None
2115
        py_stylesheet_string = None
2116
        py_save = False
2117
        cdef int option = 0
2118
        cdef PyXdmNode py_xdmNode = None
2119
        if kwds.keys() >= {"stylesheet_text", "stylesheet_file"}:
2120
          raise Exception(py_error_message)
2121
        if kwds.keys() >= {"stylesheet_text", "stylesheet_node"}:
2122
          raise Exception(py_error_message)
2123
        if kwds.keys() >= {"stylesheet_node", "stylesheet_file"}:
2124
          raise Exception(py_error_message)
2125

    
2126
        if ("save" in kwds) and kwds["save"]==True:
2127
          del kwds["save"]
2128
          if "output_file" not in kwds:
2129
            raise Exception("Output file option not in keyword arugment for compile_stylesheet")
2130
          py_output_string = kwds["output_file"].encode('UTF-8')
2131
          c_outputfile = py_output_string
2132
          if "stylesheet_text" in kwds:
2133
            py_stylesheet_string = kwds["stylesheet_text"].encode('UTF-8')
2134
            c_stylesheet = py_stylesheet_string
2135
            self.thisxptr.compileFromStringAndSave(c_stylesheet, c_outputfile)
2136
          elif "stylesheet_file" in kwds:
2137
            py_stylesheet_string = kwds["stylesheet_file"].encode('UTF-8')
2138
            if py_stylesheet_string  is None or isfile(py_stylesheet_string) == False:
2139
              raise Exception("Stylesheet file does not exist")
2140
            c_stylesheet = py_stylesheet_string
2141
            self.thisxptr.compileFromFileAndSave(c_stylesheet, c_outputfile)
2142
          elif "stylesheet_node" in kwds:
2143
            py_xdmNode = kwds["stylesheet_node"]
2144
            #if not isinstance(py_value, PyXdmNode):
2145
              #raise Exception("StylesheetNode keyword arugment is not of type XdmNode")
2146
            #value = PyXdmNode(py_value)
2147
            self.thisxptr.compileFromXdmNodeAndSave(py_xdmNode.derivednptr, c_outputfile)
2148
          else:
2149
            raise Exception(py_error_message)
2150
        else:
2151
          if "stylesheet_text" in kwds:
2152
            py_stylesheet_string = kwds["stylesheet_text"].encode('UTF-8')
2153
            c_stylesheet = py_stylesheet_string
2154
            self.thisxptr.compileFromString(c_stylesheet)
2155
          elif "stylesheet_file" in kwds:
2156
            py_stylesheet_string = kwds["stylesheet_file"].encode('UTF-8')
2157
            c_stylesheet = py_stylesheet_string
2158
            if py_stylesheet_string  is None or isfile(py_stylesheet_string) == False:
2159
              raise Exception("Stylesheet file does not exist")
2160
            self.thisxptr.compileFromFile(c_stylesheet)
2161
          elif "associated_file" in kwds:
2162
            py_stylesheet_string = kwds["associated_file"].encode('UTF-8')
2163
            if py_stylesheet_string  is None or isfile(py_stylesheet_string) == False:
2164
              raise Exception("Stylesheet file does not exist")
2165
            c_stylesheet = py_stylesheet_string
2166
            self.thisxptr.compileFromAssociatedFile(c_stylesheet)
2167
          elif "stylesheet_node" in kwds:
2168
            py_xdmNode = kwds["stylesheet_node"]
2169
            #if not isinstance(py_value, PyXdmNode):
2170
              #raise Exception("StylesheetNode keyword arugment is not of type XdmNode")
2171
            #value = PyXdmNode(py_value)
2172
            self.thisxptr.compileFromXdmNode(py_xdmNode.derivednptr)
2173
          else:
2174
            raise Exception(py_error_message)
2175

    
2176

    
2177
  
2178
     def release_stylesheet(self):
2179
        """
2180
        release_stylesheet(self)
2181
        Release cached stylesheet
2182

    
2183
        """
2184
        self.thisxptr.releaseStylesheet()
2185

    
2186
     def exception_occurred(self):
2187
        """
2188
        exception_occurred(self)
2189
        Checks for pending exceptions without creating a local reference to the exception object
2190
        Returns:
2191
            boolean: True when there is a pending exception; otherwise return False
2192

    
2193
        """
2194
        return self.thisxptr.exceptionCount() >0
2195

    
2196
     def check_exception(self):
2197
        """
2198
        check_exception(self)
2199
        Check for exception thrown and get message of the exception.
2200

    
2201
        Returns:
2202
            str: Returns the exception message if thrown otherwise return None
2203

    
2204
        """
2205
        cdef const char* c_string = self.thisxptr.checkException()
2206
        ustring = c_string.decode('UTF-8') if c_string is not NULL else None
2207
        return ustring
2208

    
2209
     def exception_clear(self):
2210
        """
2211
        exception_clear(self)
2212
        Clear any exception thrown
2213

    
2214
        """
2215
        self.thisxptr.exceptionClear()
2216

    
2217
     def exception_count(self):
2218
        """
2219
        excepton_count(self)
2220
        Get number of errors reported during execution.
2221

    
2222
        Returns:
2223
            int: Count of the exceptions thrown during execution
2224
        """
2225
        return self.thisxptr.exceptionCount()
2226

    
2227
     def get_error_message(self, index):
2228
        """
2229
        get_error_message(self, index)
2230
        A transformation may have a number of errors reported against it. Get the ith error message if there are any errors
2231

    
2232
        Args:
2233
            index (int): The i'th exception
2234

    
2235
        Returns:
2236
            str: The message of the i'th exception. Return None if the i'th exception does not exist.
2237
        """
2238
        cdef const char* c_string = self.thisxptr.getErrorMessage(index)
2239
        ustring = c_string.decode('UTF-8') if c_string is not NULL else None
2240
        return ustring
2241

    
2242
     def get_error_code(self, index):
2243
        """
2244
        get_error_code(self, index)
2245
        A transformation may have a number of errors reported against it. Get the i'th error code if there are any errors
2246

    
2247
        Args:
2248
            index (int): The i'th exception
2249

    
2250
        Returns:
2251
            str: The error code associated with the i'th exception. Return None if the i'th exception does not exist.
2252

    
2253
        """
2254
        cdef const char* c_string = self.thisxptr.getErrorCode(index)
2255
        ustring = c_string.decode('UTF-8') if c_string is not NULL else None
2256
        return ustring
2257

    
2258

    
2259

    
2260

    
2261
cdef class PyXQueryProcessor:
2262
     """An PyXQueryProcessor object represents factory to compile, load and execute queries. """
2263

    
2264
     cdef saxoncClasses.XQueryProcessor *thisxqptr      # hold a C++ instance which we're wrapping
2265

    
2266
     def __cinit__(self):
2267
        """
2268
        __cinit__(self)
2269
        Constructor for PyXQueryProcessor
2270

    
2271
        """
2272
        self.thisxqptr = NULL
2273

    
2274
     def __dealloc__(self):
2275
        """
2276
        dealloc(self)
2277

    
2278

    
2279
        """
2280
        if self.thisxqptr != NULL:
2281
           del self.thisxqptr
2282

    
2283
     def set_context(self, ** kwds):
2284
        """
2285
        set_context(self, **kwds)
2286
        Set the initial context for the query
2287
   
2288
        Args:
2289
            **kwds : Possible keyword argument file_name (str) or xdm_item (PyXdmItem)
2290

    
2291
        """
2292
        py_error_message = "Error: set_context should only contain one of the following keyword arguments: (file_name|xdm_item)"
2293
        if len(kwds) != 1:
2294
          raise Exception(py_error_message)
2295
        cdef py_value = None
2296
        cdef py_value_string = None
2297
        cdef char * c_source
2298
        cdef PyXdmItem xdm_item = None
2299
        if "file_name" in kwds:
2300
            py_value = kwds["file_name"]
2301
            py_value_string = py_value.encode('UTF-8') if py_value is not None else None
2302
            c_source = py_value_string if py_value is not None else "" 
2303
            self.thisxqptr.setContextItemFromFile(c_source)
2304
        elif "xdm_item" in kwds:
2305
            xdm_item = kwds["xdm_item"]
2306
            xdm_item.derivedptr.incrementRefCount()
2307
            self.thisxqptr.setContextItem(xdm_item.derivedptr)
2308
        else:
2309
          raise Exception(py_error_message)
2310

    
2311
     def set_output_file(self, output_file):
2312
        """
2313
        set_output_file(self, output_file)
2314
        Set the output file where the result is sent
2315

    
2316
        Args:
2317
            output_file (str): Name of the output file
2318
        """
2319
        py_value_string = output_file.encode('UTF-8') if output_file is not None else None
2320
        c_outfile = py_value_string if output_file is not None else ""
2321
        self.thisxqptr.setOutputFile(c_outfile)
2322

    
2323
     def set_parameter(self, name, PyXdmValue value):
2324
        """
2325
        set_parameter(self, name, PyXdmValue value)
2326
        Set the value of a query parameter
2327

    
2328
        Args:
2329
            name (str): the name of the stylesheet parameter, as a string. For namespaced parameter use the JAXP solution i.e. "{uri}name
2330
            value (PyXdmValue): the value of the query parameter, or None to clear a previously set value
2331

    
2332
        """
2333
        cdef const char * c_str = make_c_str(name)
2334
        if c_str is not NULL:
2335
            value.thisvptr.incrementRefCount()
2336
            self.thisxqptr.setParameter(c_str, value.thisvptr)
2337

    
2338
     def remove_parameter(self, name):
2339
        """
2340
        remove_parameter(self, name)
2341
        Remove the parameter given by name from the PyXQueryProcessor. The parameter will not have any affect on the query if it has not yet been executed
2342

    
2343
        Args:
2344
            name (str): The name of the query parameter
2345

    
2346
        Returns:
2347
            bool: True if the removal of the parameter has been successful, False otherwise.
2348

    
2349
        """
2350
        py_value_string = name.encode('UTF-8') if name is not None else None
2351
        c_name = py_value_string if name is not None else ""
2352
        self.thisxqptr.removeParameter(c_name)
2353

    
2354
     def set_property(self, name, str value):
2355
        """
2356
        set_property(self, name, value)
2357
        Set a property specific to the processor in use.
2358
 
2359
        Args:
2360
            name (str): The name of the property
2361
            value (str): The value of the property
2362

    
2363
        Example:
2364
            PyXQueryProcessor: set serialization properties (names start with '!' i.e. name "!method" -> "xml")\r
2365
            'o':outfile name,\r
2366
            'dtd': Possible values 'on' or 'off' to set DTD validation,\r 
2367
            'resources': directory to find Saxon data files,\r 
2368
            's': source as file name,\r
2369
        """
2370

    
2371
        py_name_string = name.encode('UTF-8') if name is not None else None
2372
        c_name = py_name_string if name is not None else ""
2373

    
2374
        py_value_string = value.encode('UTF-8') if value is not None else None
2375
        c_value = py_value_string if value is not None else ""
2376
        self.thisxqptr.setProperty(c_name, c_value)
2377

    
2378
     def clear_parameters(self):
2379
        """
2380
        clear_parameter(self)
2381
        Clear all parameters set on the processor
2382
        """
2383
        self.thisxqptr.clearParameters()
2384

    
2385
     def clear_properties(self):
2386
        """
2387
        clear_parameter(self)
2388
        Clear all properties set on the processor
2389
        """
2390
        self.thisxqptr.clearProperties()
2391

    
2392
     def set_updating(self, updating):
2393
        """
2394
        set_updating(self, updating)
2395
        Say whether the query is allowed to be updating. XQuery update syntax will be rejected during query compilation unless this
2396
        flag is set. XQuery Update is supported only under Saxon-EE/C.
2397

    
2398

    
2399
        Args:
2400
            updating (bool): true if the query is allowed to use the XQuery Update facility (requires Saxon-EE/C). If set to false,
2401
                             the query must not be an updating query. If set to true, it may be either an updating or a non-updating query.
2402

    
2403

    
2404
        """
2405
        self.thisxqptr.setUpdating(updating)
2406

    
2407
     def run_query_to_value(self, ** kwds):
2408
        """
2409
        run_query_to_value(self, **kwds)
2410
        Execute query and output result as an PyXdmValue object 
2411

    
2412
        Args:
2413
            **kwds: Keyword arguments with the possible options input_file_name (str) or input_xdm_item (PyXdmItem). Possible to supply
2414
                    query with the arguments 'query_file' or 'query_text', which are of type str.
2415

    
2416
        Returns:
2417
            PyXdmValue: Output result as an PyXdmValue
2418
        """
2419
        cdef PyXdmNode nval = None
2420
        cdef PyXdmAtomicValue aval = None
2421
        cdef PyXdmValue val = None
2422
        if not len(kwds) == 0:
2423
          
2424
            if "input_file_name" in kwds:
2425
                self.set_context(file_name=kwds["input_file_name"])
2426
            elif "input_xdm_item" in kwds:
2427
                self.set_context(xdm_item=(kwds["xdm_item"]))
2428

    
2429
            if "query_file" in kwds:
2430
                self.set_query_file(kwds["output_file_name"])
2431
            elif "query_text" in kwds:
2432
                self.set_query_content(kwds["query_text"])
2433
        
2434
        cdef saxoncClasses.XdmValue * xdmValue = self.thisxqptr.runQueryToValue()
2435
        if xdmValue is NULL:
2436
            return None        
2437
        cdef type_ = xdmValue.getType()
2438
        if type_== 4:
2439
            aval = PyXdmAtomicValue()
2440
            aval.derivedaptr = aval.derivedptr = aval.thisvptr = <saxoncClasses.XdmAtomicValue *>xdmValue
2441
            return aval        
2442
        elif type_ == 3:
2443
            nval = PyXdmNode()        
2444
            nval.derivednptr = nval.derivedptr = nval.thisvptr = <saxoncClasses.XdmNode*>xdmValue
2445
            return nval
2446
        else:
2447
            val = PyXdmValue()
2448
            val.thisvptr = xdmValue
2449
            return val
2450

    
2451
     def run_query_to_string(self, ** kwds):
2452
        """
2453
        run_query_to_string(self, **kwds)
2454
        Execute query and output result as a string 
2455

    
2456
        Args:
2457
            **kwds: Keyword arguments with the possible options input_file_name (str) or input_xdm_item (PyXdmItem). Possible to supply
2458
                    query with the arguments 'query_file' or 'query_text', which are of type str.
2459

    
2460
        Returns:
2461
            str: Output result as a string
2462
        """
2463
        cdef const char * c_string
2464
        if len(kwds) == 0:
2465
          ustring = make_py_str(self.thisxqptr.runQueryToString())
2466
          return ustring
2467

    
2468
        if "input_file_name" in kwds:
2469
          self.set_context(file_name=kwds["input_file_name"])
2470
        elif "input_xdm_item" in kwds:
2471
          self.set_context(xdm_item=(kwds["xdm_item"]))
2472
        if "query_file" in kwds:
2473
          self.set_query_file(kwds["output_file_name"])
2474
        elif "query_text" in kwds:
2475
          self.set_query_content(kwds["query_text"])
2476
    
2477
        ustring = make_py_str(self.thisxqptr.runQueryToString())
2478
        return ustring
2479
        
2480

    
2481
     def run_query_to_file(self, ** kwds):
2482
        """
2483
        run_query_to_file(self, **kwds)
2484
        Execute query with the result saved to file
2485

    
2486
        Args:
2487
            **kwds: Keyword arguments with the possible options input_file_name (str) or input_xdm_item (PyXdmItem). The Query can be
2488
                    supplied with the arguments 'query_file' or 'query_text', which are of type str. The name of the output file is
2489
                    specified as the argument output_file_name.
2490

    
2491

    
2492
        """
2493
        if len(kwds) == 0:
2494
          self.thisxqptr.runQueryToFile()
2495
        if "input_file_name" in kwds:
2496
          self.set_context(file_name=(kwds["input_file_name"]))
2497
        elif "input_xdm_item" in kwds:
2498
          self.set_context(xdm_item=(kwds["xdm_item"]))
2499
        if "output_file_name" in kwds:
2500
          self.set_output_file(kwds["output_file_name"])
2501
        else:
2502
          raise Exception("Error: output_file_name required in method run_query_to_file")
2503

    
2504
        if "query_file" in kwds:
2505
          self.set_query_file(kwds["output_file_name"])
2506
        elif "query_text" in kwds:
2507
          self.set_query_content(kwds["query_text"])
2508
        self.thisxqptr.runQueryToFile()
2509

    
2510
     def declare_namespace(self, prefix, uri):
2511
        """
2512
        declare_namespace(self, prefix, uri)
2513
        Declare a namespace binding part of the static context for queries compiled using this.
2514
        This binding may be overridden by a binding that appears in the query prolog.
2515
        The namespace binding will form part of the static context of the query, but it will
2516
        not be copied into result trees unless the prefix is actually used in an element or attribute name.
2517

    
2518
        Args:
2519
            prefix (str): The namespace prefix. If the value is a zero-length string, this method sets the default namespace for elements and types.
2520
            uri (uri) : The namespace URI. It is possible to specify a zero-length string to "undeclare" a namespace; in this case the prefix will not be available for use,
2521
            except in the case where the prefix is also a zero length string, in which case the absence of a prefix implies that the name is in no namespace.
2522

    
2523
        """
2524
        c_prefix = make_c_str(prefix)
2525
        c_uri = make_c_str(uri)
2526
        self.thisxqptr.declareNamespace(c_prefix, c_uri)
2527

    
2528
     def set_query_file(self, file_name):
2529
        """
2530
        set_query_file(self, file_name)
2531
        Set the query to be executed as a file
2532

    
2533
        Args:
2534
            file_name (str): The file name for the query
2535

    
2536

    
2537
        """
2538
        c_filename = make_c_str(file_name)
2539
        self.thisxqptr.setQueryFile(c_filename)
2540

    
2541
     def set_query_content(self, content):
2542
        """
2543
        set_query_content(self)
2544
        Set the query to be executed as a string
2545

    
2546
        Args:
2547
            content (str): The query content suplied as a string
2548

    
2549
        """
2550
        if content is not None:
2551
            c_content = make_c_str(content)
2552
            self.thisxqptr.setQueryContent(c_content)
2553

    
2554
     def set_query_base_uri(self, base_uri):
2555
        """
2556
        set_query_base_uri(self, base_uri)
2557
        Set the static base query for the query     
2558

    
2559
        Args:
2560
            base_uri (str): The static base URI; or None to indicate that no base URI is available
2561
        """
2562
        py_content_string = base_uri.encode('UTF-8') if base_uri is not None else None
2563
        c_content = py_content_string if base_uri is not None else ""
2564
        self.thisxqptr.setQueryBaseURI(c_content)
2565

    
2566
     def set_cwd(self, cwd):
2567
        """
2568
        set_cwd(self, cwd)
2569
        Set the current working directory.
2570

    
2571
        Args:
2572
            cwd (str): current working directory
2573
        """
2574
        py_cwd_string = cwd.encode('UTF-8') if cwd is not None else None
2575
        c_cwd = py_cwd_string if cwd is not None else ""
2576
        self.thisxqptr.setcwd(c_cwd)
2577

    
2578
     def check_exception(self):
2579
        """
2580
        check_exception(self)
2581
        Check for exception thrown and get message of the exception.
2582
  
2583
        Returns:
2584
            str: Returns the exception message if thrown otherwise return None
2585

    
2586
        """
2587
        return self.thisxqptr.checkException()
2588

    
2589
     def exception_occurred(self):
2590
        """
2591
        exception_occurred(self)
2592
        Checks for pending exceptions without creating a local reference to the exception object
2593

    
2594
        Returns:
2595
            boolean: True when there is a pending exception; otherwise return False
2596

    
2597
        """
2598
        return self.thisxqptr.exceptionCount() >0
2599

    
2600
     def exception_clear(self):
2601
        """
2602
        exception_clear(self)
2603
        Clear any exception thrown
2604

    
2605
        """
2606
        self.thisxqptr.exceptionClear()
2607

    
2608
     def exception_count(self):
2609
        """
2610
        excepton_count(self)
2611
        Get number of errors reported during execution.
2612

    
2613
        Returns:
2614
            int: Count of the exceptions thrown during execution
2615
        """
2616
        return self.thisxqptr.exceptionCount()
2617

    
2618
     def get_error_message(self, index):
2619
        """
2620
        get_error_message(self, index)
2621
        A transformation may have a number of errors reported against it. Get the ith error message if there are any errors
2622

    
2623
        Args:
2624
            index (int): The i'th exception
2625
        
2626
        Returns:
2627
            str: The message of the i'th exception. Return None if the i'th exception does not exist.
2628
        """
2629
        return make_py_str(self.thisxqptr.getErrorMessage(index))
2630

    
2631
     def get_error_code(self, index):
2632
        """
2633
        get_error_code(self, index)
2634
        A transformation may have a number of errors reported against it. Get the i'th error code if there are any errors
2635

    
2636
        Args:
2637
            index (int): The i'th exception
2638
        
2639
        Returns:
2640
            str: The error code associated with the i'th exception. Return None if the i'th exception does not exist.
2641

    
2642
        """
2643
        return make_py_str(self.thisxqptr.getErrorCode(index))
2644

    
2645
cdef class PyXPathProcessor:
2646
     """An XPathProcessor represents factory to compile, load and execute the XPath query. """
2647
     cdef saxoncClasses.XPathProcessor *thisxpptr      # hold a C++ instance which we're wrapping
2648

    
2649
     def __cinit__(self):
2650
        """
2651
        cinit(self)
2652
        Constructor for PyXPathProcessor 
2653

    
2654
        """
2655
        self.thisxpptr = NULL
2656
     def __dealloc__(self):
2657
        """
2658
        dealloc(self)
2659

    
2660

    
2661
        """
2662
        if self.thisxpptr != NULL:
2663
           del self.thisxpptr
2664

    
2665

    
2666
     def evaluate(self, xpath_str):
2667
        """
2668
        evaluate(self, xpath_str)
2669

    
2670
        Args:
2671
            xpath_str (str): The XPath query suplied as a string
2672

    
2673
        Returns:
2674
            PyXdmValue: 
2675

    
2676
        """
2677
        py_string = xpath_str.encode('UTF-8') if xpath_str is not None else None
2678
        c_xpath = py_string if xpath_str is not None else ""
2679
        cdef PyXdmNode nval = None
2680
        cdef PyXdmAtomicValue aval = None
2681
        cdef PyXdmValue val = None
2682
        cdef type_ = 0
2683
        cdef saxoncClasses.XdmValue * xdmValue = self.thisxpptr.evaluate(c_xpath)
2684
        if xdmValue == NULL:
2685
            return None
2686
        else:
2687
            type_ = xdmValue.getType()        
2688
            if type_ == 4:
2689
                aval = PyXdmAtomicValue()
2690
                aval.derivedaptr = aval.derivedptr = aval.thisvptr = <saxoncClasses.XdmAtomicValue *>xdmValue
2691
                return aval        
2692
            elif type_ == 3:
2693
                nval = PyXdmNode()
2694
                nval.derivednptr = nval.derivedptr = nval.thisvptr = <saxoncClasses.XdmNode*>xdmValue
2695
                return nval
2696
            else:
2697
                val = PyXdmValue()
2698
                val.thisvptr = xdmValue
2699
                return val
2700

    
2701
     def evaluate_single(self, xpath_str):
2702
        """
2703
        evaluate_single(self, xpath_str)
2704

    
2705
        Args:
2706
            xpath_str (str): The XPath query supplied as a string
2707

    
2708
        Returns:
2709
            PyXdmItem: A single Xdm Item is returned. return None if the expression returns an empty sequence.
2710
            If the expression returns a sequence of more than one item, any items after the first are ignored.
2711

    
2712
        """
2713
        cdef PyXdmNode val = None
2714
        cdef PyXdmAtomicValue aval = None
2715
        py_string = xpath_str.encode('UTF-8') if xpath_str is not None else None
2716
        c_xpath = py_string if xpath_str is not None else ""
2717

    
2718
        cdef saxoncClasses.XdmItem * xdmItem = self.thisxpptr.evaluateSingle(c_xpath)
2719
        if xdmItem == NULL:
2720
            return None
2721
        cdef type_ = xdmItem.getType()        
2722
        if type_ == 4:
2723
            aval = PyXdmAtomicValue()
2724
            aval.derivedaptr = aval.derivedptr = aval.thisvptr = <saxoncClasses.XdmAtomicValue *>xdmItem
2725
            return aval        
2726
        elif type_ == 3:
2727
            val = PyXdmNode()
2728
            val.derivednptr = val.derivedptr = val.thisvptr = <saxoncClasses.XdmNode*>xdmItem
2729
            return val
2730
        else:
2731
            return None
2732
        
2733

    
2734
     def set_context(self, **kwds):
2735
        """
2736
        set_context(self, **kwds)
2737
        Set the context for the XPath query
2738
   
2739
        Args:
2740
            **kwds : Possible keyword argument file_name (str) or xdm_item (PyXdmItem)
2741

    
2742
        """
2743
        py_error_message = "Error: set_context should only contain one of the following keyword arguments: (file_name|xdm_item)"
2744
        if len(kwds) != 1:
2745
          raise Exception(py_error_message)
2746
        cdef py_value = None
2747
        cdef py_value_string = None
2748
        cdef char * c_source
2749
        cdef PyXdmItem xdm_item = None
2750
        if "file_name" in kwds:
2751
            py_value = kwds["file_name"]
2752
            py_value_string = py_value.encode('UTF-8') if py_value is not None else None
2753
            c_source = py_value_string if py_value is not None else "" 
2754
            self.thisxpptr.setContextFile(c_source)
2755
        elif "xdm_item" in kwds:
2756
            xdm_item = kwds["xdm_item"]
2757
            xdm_item.derivedptr.incrementRefCount()
2758
            self.thisxpptr.setContextItem(xdm_item.derivedptr)
2759
        else:
2760
          raise Exception(py_error_message)
2761

    
2762
     def set_cwd(self, cwd):
2763
        """
2764
        set_cwd(self, cwd)
2765
        Set the current working directory.
2766

    
2767
        Args:
2768
            cwd (str): current working directory
2769
        """
2770
        py_cwd_string = cwd.encode('UTF-8') if cwd is not None else None
2771
        cdef char * c_cwd = py_cwd_string if cwd is not None else "" 
2772
        self.thisxpptr.setcwd(c_cwd)
2773

    
2774
     def effective_boolean_value(self, xpath_str):
2775
        """
2776
        effective_boolean_value(self, xpath_str)
2777
        Evaluate the XPath expression, returning the effective boolean value of the result.
2778
    
2779
        Args:
2780
            xpath_str (str): Supplied as a string
2781

    
2782
        Returns:
2783
            boolean: The result is a boolean value.
2784
        """
2785

    
2786
        py_value_string = xpath_str.encode('UTF-8') if xpath_str is not None else None
2787
        c_xpath = py_value_string if xpath_str is not None else "" 
2788

    
2789
        return self.thisxpptr.effectiveBooleanValue(c_xpath)
2790

    
2791
     def set_parameter(self, name, PyXdmValue value):
2792
        """
2793
        set_parameter(self, name, PyXdmValue value)
2794
        Set the value of a XPath parameter
2795

    
2796
        Args:
2797
            name (str): the name of the XPath parameter, as a string. For namespaced parameter use the JAXP solution i.e. "{uri}name
2798
            value (PyXdmValue): the value of the query parameter, or None to clear a previously set value
2799

    
2800
        """
2801
        cdef const char * c_str = make_c_str(name)
2802
        if c_str is not NULL:
2803
            self.thisxpptr.setParameter(c_str, value.thisvptr)
2804

    
2805
     def remove_parameter(self, name):
2806
        """
2807
        remove_parameter(self, name)
2808
        Remove the parameter given by name from the PyXPathProcessor. The parameter will not have any affect on the XPath if it has not yet been executed
2809

    
2810
        Args:
2811
            name (str): The name of the XPath parameter
2812

    
2813
        Returns:
2814
            bool: True if the removal of the parameter has been successful, False otherwise.
2815

    
2816
        """
2817
        self.thisxpptr.removeParameter(name)
2818
     def set_property(self, name, value):
2819
        """
2820
        set_property(self, name, value)
2821
        Set a property specific to the processor in use.
2822
 
2823
        Args:
2824
            name (str): The name of the property
2825
            value (str): The value of the property
2826

    
2827
        Example:
2828
            PyXPathProcessor: set serialization properties (names start with '!' i.e. name "!method" -> "xml")\r
2829
            'resources': directory to find Saxon data files,\r 
2830
            's': source as file name,\r
2831
            'extc': REgister native library to be used with extension functions
2832
        """
2833

    
2834
        py_name_string = name.encode('UTF-8') if name is not None else None
2835
        c_name = py_name_string if name is not None else ""
2836

    
2837
        py_value_string = value.encode('UTF-8') if value is not None else None
2838
        c_value = py_value_string if value is not None else ""
2839
        self.thisxpptr.setProperty(c_name, c_value)
2840
     def declare_namespace(self, prefix, uri):
2841
        """
2842
        declare_namespace(self, prefix, uri)
2843
        Declare a namespace binding as part of the static context for XPath expressions compiled using this compiler
2844
        Args:
2845
            prefix (str): The namespace prefix. If the value is a zero-length string, this method sets the default namespace
2846
                          for elements and types.
2847
            uri (uri) : The namespace URI. It is possible to specify a zero-length string to "undeclare" a namespace;
2848
                        in this case the prefix will not be available for use, except in the case where the prefix is also a
2849
                        zero length string, in which case the absence of a prefix implies that the name is in no namespace.
2850

    
2851
        """
2852
        py_prefix_string = prefix.encode('UTF-8') if prefix is not None else None
2853
        c_prefix = py_prefix_string if prefix is not None else ""
2854
        py_uri_string = uri.encode('UTF-8') if uri is not None else None
2855
        c_uri = py_uri_string if uri is not None else ""
2856
        self.thisxpptr.declareNamespace(c_prefix, c_uri)
2857

    
2858
     def set_backwards_compatible(self, option):
2859
        cdef bool c_option
2860
        c_option = option
2861
        self.thisxpptr.setBackwardsCompatible(c_option)
2862

    
2863
     def set_caching(self, is_caching):
2864
         cdef bool c_is_caching
2865
         c_is_caching = is_caching
2866
         self.thisxpptr.setCaching(c_is_caching)
2867

    
2868
     def import_schema_namespace(self, uri):
2869
         py_uri_string = uri.encode('UTF-8') if uri is not None else None
2870
         c_name = py_uri_string if uri is not None else ""
2871
         self.thisxpptr.importSchemaNamespace(c_name)
2872

    
2873
     def clear_parameters(self):
2874
        """
2875
        clear_parameter(self)
2876
        Clear all parameters set on the processor
2877
        """
2878
        self.thisxpptr.clearParameters()
2879
     def clear_properties(self):
2880
        """
2881
        clear_parameter(self)
2882
        Clear all properties set on the processor
2883
        """
2884
        self.thisxpptr.clearProperties()
2885
     def check_exception(self):
2886
        """
2887
        check_exception(self)
2888
        Check for exception thrown and get message of the exception.
2889
  
2890
        Returns:
2891
            str: Returns the exception message if thrown otherwise return None
2892

    
2893
        """
2894
        return self.thisxpptr.checkException()
2895
     def exception_occurred(self):
2896
        """
2897
        exception_occurred(self)
2898
        Check if an exception has occurred internally within Saxon/C
2899

    
2900
        Returns:
2901
            boolean: True or False if an exception has been reported internally in Saxon/C
2902
        """
2903

    
2904
        return self.thisxpptr.exceptionCount() >0
2905

    
2906
     def exception_clear(self):
2907
        """
2908
        exception_clear(self)
2909
        Clear any exception thrown
2910

    
2911
        """
2912
        self.thisxpptr.exceptionClear()
2913
     def exception_count(self):
2914
        """
2915
        excepton_count(self)
2916
        Get number of errors reported during execution.
2917

    
2918
        Returns:
2919
            int: Count of the exceptions thrown during execution
2920
        """
2921
        return self.thisxpptr.exceptionCount()
2922
     def get_error_message(self, index):
2923
        """
2924
        get_error_message(self, index)
2925
        A transformation may have a number of errors reported against it. Get the ith error message if there are any errors
2926

    
2927
        Args:
2928
            index (int): The i'th exception
2929
        
2930
        Returns:
2931
            str: The message of the i'th exception. Return None if the i'th exception does not exist.
2932
        """
2933
        return make_py_str(self.thisxpptr.getErrorMessage(index))
2934
     def get_error_code(self, index):
2935
        """
2936
        get_error_code(self, index)
2937
        A transformation may have a number of errors reported against it. Get the i'th error code if there are any errors
2938

    
2939
        Args:
2940
            index (int): The i'th exception
2941
        
2942
        Returns:
2943
            str: The error code associated with the i'th exception. Return None if the i'th exception does not exist.
2944

    
2945
        """
2946
        return make_py_str(self.thisxpptr.getErrorCode(index))
2947

    
2948

    
2949
cdef class PySchemaValidator:
2950
     """An PySchemaValidator represents factory for validating instance documents against a schema."""
2951
     
2952
     cdef saxoncClasses.SchemaValidator *thissvptr      # hold a C++ instance which we're wrapping
2953

    
2954
     def __cinit__(self):
2955
        self.thissvptr = NULL
2956
     def __dealloc__(self):
2957
        if self.thissvptr != NULL:
2958
           del self.thissvptr
2959

    
2960
     def set_cwd(self, cwd):
2961
        """
2962
        set_cwd(self, cwd)
2963
        Set the current working directory.
2964

    
2965
        Args:
2966
            cwd (str): current working directory
2967
        """
2968
        py_cwd_string = cwd.encode('UTF-8') if cwd is not None else None
2969
        cdef char * c_cwd = py_cwd_string if cwd is not None else "" 
2970
        self.thissvptr.setcwd(c_cwd)
2971

    
2972
     def register_schema(self, **kwds):
2973
        """
2974
        Register schema given as file name or schema text. (xsd_text|xsd_file)
2975

    
2976
        Args:
2977
            **kwds: Keyword argument options only one of 'xsd_text' or 'xsd_file'
2978

    
2979
        """
2980
        py_error_message = "Error: register_schema should only contain one of the following keyword arguments: (xsd_text|xsd_file)"
2981
        if len(kwds) != 1:
2982
          raise Exception(py_error_message)
2983
        cdef py_value = None
2984
        cdef py_value_string = None
2985
        cdef char * c_source
2986
        
2987
        if "xsd_text" in kwds:
2988
            py_value = kwds["xsd_text"]
2989
            py_value_string = py_value.encode('UTF-8') if py_value is not None else None
2990
            c_source = py_value_string if py_value is not None else "" 
2991
            self.thissvptr.registerSchemaFromString(c_source)
2992
        elif "xsd_file" in kwds:
2993
            py_value = kwds["xsd_file"]
2994
            py_value_string = py_value.encode('UTF-8') if py_value is not None else None
2995
            c_source = py_value_string if py_value is not None else "" 
2996
            self.thissvptr.registerSchemaFromFile(c_source)
2997
        else:
2998
          raise Exception(py_error_message)
2999

    
3000
     def export_schema(self, file_name):
3001
        """
3002
        export_schema(self, file_name)
3003
        Export a precompiled Schema Component Model containing all the components (except built-in components) that have been loaded
3004

    
3005
        Args:
3006
            file_name (str):The file name that will be used for thje saved SCM
3007

    
3008
        """
3009
        py_value_string = file_name.encode('UTF-8') if file_name is not None else None
3010
        c_source = py_value_string
3011
        if file_name is not None:
3012
            self.thissvptr.exportSchema(c_source)
3013
        else:
3014
            raise Warning("Unable to export the Schema. file_name has the value None")
3015

    
3016
        
3017
     def set_output_file(self, output_file):
3018
        """
3019
        set_output_file(self, output_file)
3020
        Set the name of the output file that will be used by the validator.
3021

    
3022
        Args:
3023
            output_file (str):The output file name for use by the validator
3024
    
3025
        """
3026
        py_value_string = output_file.encode('UTF-8') if output_file is not None else None
3027
        c_source = py_value_string 
3028
        if output_file is not None:
3029
            self.thissvptr.setOutputFile(c_source)
3030
        else:
3031
            raise Warning("Unable to set output_file. output_file has the value None")
3032

    
3033
     def validate(self, **kwds):
3034
        """
3035
        validate(self, **kwds)
3036
        Validate an instance document by a registered schema.
3037
        
3038
        Args:
3039
            **kwds: The possible keyword arguments must be one of the follow (file_name|xml_text|xdm_node).
3040
                    The source file to be validated. Allow None when source document is supplied using the set_source method
3041
        """
3042
        py_error_message = "Error: validate should only contain one of the following keyword arguments: (file_name|xdm_node|xml_text)"
3043
        if len(kwds) > 1:
3044
          raise Exception(py_error_message)
3045
        cdef py_value = None
3046
        cdef py_value_string = None
3047
        cdef char * c_source
3048
        cdef PyXdmNode xdm_node = None
3049
        if "file_name" in kwds:
3050
            py_value = kwds["file_name"]
3051
            py_value_string = py_value.encode('UTF-8') if py_value is not None else None
3052
            c_source = py_value_string if py_value is not None else ""
3053
            self.thissvptr.validate(c_source)
3054
        elif "xdm_node" in kwds:
3055
            xdm_node = kwds["xdm_node"]
3056
            if isinstance(xdm_node, PyXdmNode):
3057
               self.thissvptr.setSourceNode(xdm_node.derivednptr)
3058
               self.thissvptr.validate(NULL)
3059
        else:
3060
            self.thissvptr.validate(NULL)
3061

    
3062

    
3063
     def validate_to_node(self, **kwds):
3064
        """
3065
        validate_to_node(self, **kwds)
3066
        Validate an instance document by a registered schema.
3067
        
3068

    
3069
        Args:
3070
            **kwds: The possible keyword arguments must be one of the follow (file_name|xml_text|xdm_node).
3071
                    The source file to be validated. Allow None when source document is supplied using the set_source method
3072

    
3073
        Returns:
3074
            PyXdmNode: The validated document returned to the calling program as an PyXdmNode    
3075
        """
3076
        py_error_message = "Error: validate should only contain one of the following keyword arguments: (file_name|xdm_node|xml_text)"
3077
        if len(kwds) > 1:
3078
          raise Exception(py_error_message)
3079
        cdef py_value = None
3080
        cdef py_value_string = None
3081
        cdef char * c_source
3082
        cdef PyXdmNode xdm_node = None
3083
        cdef PyXdmNode val = None
3084
        cdef saxoncClasses.XdmNode * xdmNode = NULL
3085

    
3086
        if "file_name" in kwds:
3087
            py_value = kwds["file_name"]
3088
            py_value_string = py_value.encode('UTF-8') if py_value is not None else None
3089
            c_source = py_value_string if py_value is not None else ""
3090
            if isfile(py_value_string) == False:
3091
                raise Exception("Source file with name "+py_value_string+" does not exist")
3092
            xdmNode = self.thissvptr.validateToNode(c_source)
3093
        elif "xdm_node" in kwds:
3094
            xdm_node = kwds["xdm_node"]
3095
            if isinstance(xdm_node, PyXdmNode):
3096
                self.thissvptr.setSourceNode(xdm_node.derivednptr)
3097
                xdmNode = self.thissvptr.validateToNode(NULL)
3098
        else:
3099
            xdmNode = self.thissvptr.validateToNode(NULL)
3100
            
3101
        if xdmNode == NULL:
3102
            return None
3103
        else:
3104
            val = PyXdmNode()
3105
            val.derivednptr = val.derivedptr = val.thisvptr =  xdmNode
3106
            return val
3107

    
3108
     def set_source_node(self, PyXdmNode source):
3109
        """
3110
        set_source_node(self, source)
3111
        Set the source as an PyXdmNode object that will be validated
3112

    
3113
        Args:
3114
            source (PyXdmNode) :
3115
        """
3116
        self.thissvptr.setSourceNode(source.derivednptr)
3117

    
3118
     @property
3119
     def validation_report(self):
3120
        """
3121
        validation_report
3122
        The validation report Property
3123

    
3124
        :PyXdmNode: The Validation report result from the Schema validator
3125

    
3126
        """
3127
        cdef PyXdmNode val = None
3128
        cdef saxoncClasses.XdmNode * xdmNode = NULL
3129
        xdmNode = self.thissvptr.getValidationReport()
3130
        if xdmNode == NULL:
3131
            return None
3132
        else:
3133
            val = PyXdmNode()
3134
            val.derivednptr = val.derivedptr = val.thisvptr = xdmNode
3135
            return val
3136

    
3137
     def set_parameter(self, name, PyXdmValue value):
3138
        """
3139
        set_parameter(self, name, PyXdmValue value)
3140
        Set the value of the parameter for the Schema validator
3141

    
3142
        Args:
3143
            name (str): the name of the schema parameter, as a string. For namespaced parameter use the JAXP solution i.e. "{uri}name
3144
            value (PyXdmValue): the value of the parameter, or None to clear a previously set value
3145

    
3146
        """
3147
        cdef const char * c_str = make_c_str(name)
3148
        if c_str is not NULL:
3149
            value.thisvptr.incrementRefCount()
3150
            self.thissvptr.setParameter(c_str, value.thisvptr)
3151

    
3152
     def remove_parameter(self, name):
3153
        """
3154
        remove_parameter(self, name)
3155
        Remove the parameter given by name from the PySchemaValidator. The parameter will not have any affect on the SchemaValidator if it has not yet been executed
3156

    
3157
        Args:
3158
            name (str): The name of the schema parameter
3159

    
3160
        Returns:
3161
            bool: True if the removal of the parameter has been successful, False otherwise.
3162

    
3163
        """
3164
        cdef const char * c_str = make_c_str(name)
3165
        if c_str is not NULL:
3166
            self.thissvptr.removeParameter(c_str)
3167
     def set_property(self, name, value):
3168
        """
3169
        set_property(self, name, value)
3170
        Set a property specific to the processor in use.
3171
 
3172
        Args:
3173
            name (str): The name of the property
3174
            value (str): The value of the property
3175

    
3176
        Example:
3177
            PySchemaValidator: set serialization properties (names start with '!' i.e. name "!method" -> "xml")\r
3178
            'o':outfile name,\r
3179
            'dtd': Possible values 'on' or 'off' to set DTD validation,\r 
3180
            'resources': directory to find Saxon data files,\r 
3181
            's': source as file name,\r
3182
            'string': Set the source as xml string for validation. Parsing will take place in the validate method\r
3183
            'report-node': Boolean flag for validation reporting feature. Error validation failures are represented in an XML
3184
                           document and returned as an PyXdmNode object\r
3185
            'report-file': Specifcy value as a file name string. This will switch on the validation reporting feature, which will be
3186
                           saved to the file in an XML format\r
3187
            'verbose': boolean value which sets the verbose mode to the output in the terminal. Default is 'on'
3188
            'element-type': Set the name of the required type of the top-lelvel element of the doucment to be validated.
3189
                            The string should be in the Clark notation {uri}local\r
3190
            'lax': Boolean to set the validation mode to strict (False) or lax ('True')
3191
        """
3192

    
3193
        cdef const char * c_name = make_c_str(name)
3194
        cdef const char * c_value = make_c_str(value)
3195
        if c_name is not NULL:
3196
            if c_value is not NULL:
3197
                self.thissvptr.setProperty(c_name, c_value)
3198

    
3199
     def clear_parameters(self):
3200
        """
3201
        clear_parameter(self)
3202
        Clear all parameters set on the processor
3203
        """
3204
        self.thissvptr.clearParameters()
3205
     def clear_properties(self):
3206
        """
3207
        clear_parameter(self)
3208
        Clear all properties set on the processor
3209
        """
3210
        self.thissvptr.clearProperties()
3211
     def exception_occurred(self):
3212
        """
3213
        exception_occurred(self)
3214
        Check if an exception has occurred internally within Saxon/C
3215

    
3216
        Returns:
3217
            boolean: True or False if an exception has been reported internally in Saxon/C
3218
        """
3219
        return self.thissvptr.exceptionCount()>0
3220

    
3221
     def exception_clear(self):
3222
        """
3223
        exception_clear(self)
3224
        Clear any exception thrown
3225

    
3226
        """
3227
        self.thissvptr.exceptionClear()
3228
     def exception_count(self):
3229
        """
3230
        excepton_count(self)
3231
        Get number of errors reported during execution of the schema.
3232

    
3233
        Returns:
3234
            int: Count of the exceptions thrown during execution
3235
        """
3236
        return self.thissvptr.exceptionCount()
3237
     def get_error_message(self, index):
3238
        """
3239
        get_error_message(self, index)
3240
        A transformation may have a number of errors reported against it. Get the ith error message if there are any errors
3241

    
3242
        Args:
3243
            index (int): The i'th exception
3244
        
3245
        Returns:
3246
            str: The message of the i'th exception. Return None if the i'th exception does not exist.
3247
        """
3248
        return make_py_str(self.thissvptr.getErrorMessage(index))
3249

    
3250
     def get_error_code(self, index):
3251
        """
3252
        get_error_code(self, index)
3253
        A transformation may have a number of errors reported against it. Get the i'th error code if there are any errors.
3254

    
3255
        Args:
3256
            index (int): The i'th exception
3257
        
3258
        Returns:
3259
            str: The error code associated with the i'th exception. Return None if the i'th exception does not exist.
3260

    
3261
        """
3262
        return make_py_str(self.thissvptr.getErrorCode(index))
3263

    
3264
     def set_lax(self, lax):
3265
        """
3266
        set_lax(self, lax)
3267
        The validation mode may be either strict or lax. \r
3268
        The default is strict; this method may be called to indicate that lax validation is required. With strict validation,
3269
        validation fails if no element declaration can be located for the outermost element. With lax validation,
3270
        the absence of an element declaration results in the content being considered valid.
3271
        
3272
        Args:
3273
            lax (boolean): lax True if validation is to be lax, False if it is to be strict
3274

    
3275
        """
3276
        self.thissvptr.setLax(lax)
3277

    
3278
cdef class PyXdmValue:
3279
     """Value in the XDM data model. A value is a sequence of zero or more items, each item being either an atomic value or a node. """    
3280
     cdef saxoncClasses.XdmValue *thisvptr      # hold a C++ instance which we're wrapping
3281

    
3282
     def __cinit__(self):
3283
        """
3284
        cinit(self)
3285
        Constructor for PyXdmValue
3286

    
3287
        """
3288
        if type(self) is PyXdmValue:
3289
            self.thisvptr = new saxoncClasses.XdmValue() 
3290
     def __dealloc__(self):
3291
        if type(self) is PyXdmValue and self.thisvptr != NULL:
3292
            if self.thisvptr.getRefCount() < 1:
3293
                del self.thisvptr            
3294
            else:
3295
                self.thisvptr.decrementRefCount()
3296

    
3297

    
3298
     def add_xdm_item(self, PyXdmItem value):
3299
        """
3300
        add_xdm_tem(self, PyXdmItem value)
3301
        Add PyXdmItem to the Xdm sequence
3302

    
3303
        Args:
3304
            value (PyXdmItem): The PyXdmItem object
3305
        """
3306
        self.thisvptr.addXdmItem(value.derivedptr)
3307

    
3308
     @property
3309
     def head(self):
3310
        """
3311
        head(self)
3312
        Property to get the first item in the sequence
3313

    
3314
        Returns:
3315
            PyXdmItem: The PyXdmItem or None if the sequence is empty
3316

    
3317
        """
3318
        cdef PyXdmItem val = PyXdmItem()
3319
        val.derivedptr = val.thisvptr = self.thisvptr.getHead()
3320
        if val.derivedptr == NULL :
3321
            return None
3322
        else:
3323
            val.derivedptr.incrementRefCount()
3324
            return val
3325

    
3326
     def item_at(self, index):
3327
        """
3328
        item_at(self, index)
3329
        Get the n'th item in the value, counting from zero.
3330
        
3331
        Args:
3332
            index (int): the index of the item required. Counting from zero
3333
        Returns:
3334
            PyXdmItem: Get the item indicated at the index. This could be PyXdmNode or PyXdmAtomicValue object. If the item does not exist return None.
3335
        
3336

    
3337
        """
3338
        cdef PyXdmValue val = None
3339
        cdef PyXdmAtomicValue aval = None
3340
        cdef PyXdmNode nval = None
3341
        cdef PyXdmItem val = None
3342
        cdef type_ = None
3343
        cdef saxoncClasses.XdmItem * xdmItem = NULL
3344
        xdmItem = self.thisvptr.itemAt(index)
3345
        if xdmItem == NULL:
3346
            return None
3347
        else :
3348
            type_ = xdmItem.getType()
3349

    
3350
            xdmItem.incrementRefCount()
3351
            if type_== 4:
3352
                aval = PyXdmAtomicValue()
3353
                aval.derivedaptr = aval.derivedptr = aval.thisvptr = <saxoncClasses.XdmAtomicValue *>xdmItem
3354
                return aval
3355
            elif type_ == 3:
3356
                nval = PyXdmNode()
3357
                nval.derivednptr = nval.derivedptr = nval.thisvptr = <saxoncClasses.XdmNode*>xdmItem
3358
                return nval
3359
            else:
3360
                val = PyXdmItem()
3361
                val.thisvptr = xdmItem
3362
                return val
3363

    
3364
     @property
3365
     def size(self):
3366
        """
3367
        size(self)
3368
        Property - Get the number of items in the sequence
3369
        
3370
        Returns:
3371
            int: The count of items in the sequence
3372
        """
3373
        return self.thisvptr.size()
3374

    
3375
     def __repr__(self):
3376
        """
3377
        __repr__(self)
3378
        The string representation of PyXdmItem
3379

    
3380
        """
3381
        cdef const char* c_string = self.thisvptr.toString()
3382
        if c_string == NULL:
3383
            raise Warning('Empty string returned')
3384
        else:
3385
            ustring = c_string.decode('UTF-8') if c_string is not NULL else None
3386
            return ustring
3387

    
3388
     def __str__(self):
3389
        """
3390
        __str__(self)
3391
        The string representation of PyXdmItem
3392

    
3393
        """
3394
        cdef const char* c_string = self.thisvptr.toString()
3395
        ustring = c_string.decode('UTF-8') if c_string is not NULL else None
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

    
3419

    
3420
cdef class PyXdmItem(PyXdmValue):
3421
     cdef saxoncClasses.XdmItem *derivedptr      # hold a C++ instance which we're wrapping
3422

    
3423
     def __cinit__(self):
3424
        if type(self) is PyXdmItem:
3425
            self.derivedptr = self.thisvptr = new saxoncClasses.XdmItem()
3426
     def __dealloc__(self):
3427
        if type(self) is PyXdmItem and self.derivedptr != NULL:
3428
            if self.derivedptr.getRefCount() < 1:
3429
                del self.derivedptr            
3430
            else:
3431
                self.derivedptr.decrementRefCount()
3432

    
3433
        '''if type(self) is PyXdmItem:
3434
            del self.derivedptr'''
3435

    
3436
     @property
3437
     def string_value(self):
3438
        """
3439
        string_value(self)
3440
        Property to get the the strign value of the XdmItem 
3441
        """
3442
        cdef const char* c_string = self.derivedptr.getStringValue()
3443
        ustring = c_string.decode('UTF-8') if c_string is not NULL else None
3444
        return ustring
3445

    
3446

    
3447
     def __repr__(self):
3448
        return make_py_str(self.derivedptr.getStringValue())
3449

    
3450
     def __str__(self):
3451
        return make_py_str(self.derivedptr.getStringValue())
3452

    
3453
     @property
3454
     def is_atomic(self):
3455
        """
3456
        is_atomic(self)
3457
        Property to check if the current PyXdmItem is an atomic value
3458
    
3459
        Returns:
3460
            bool: Check of is atomic value 
3461
        """
3462
        return self.derivedptr.isAtomic()
3463

    
3464
     def get_node_value(self):
3465
        """
3466
        get_node_value(self)
3467
        Get the subclass PyXdmNode for this PyXdmItem object current object if it is a node value
3468
    
3469
        Returns:
3470
            PyXdmNode: Subclass this object to PyXdmNode or error 
3471
        """
3472
        cdef PyXdmNode val = None
3473
        if self.is_atomic:
3474
          raise Exception("The PyXdmItem is an PyXdmAtomicValue therefore cannot be sub-classed to an PyXdmNode")
3475
        val = PyXdmNode()
3476
        val.derivednptr = val.derivedptr = <saxoncClasses.XdmNode*> self.derivedptr
3477
        '''val.derivednptr.incrementRefCount()'''
3478
        return val
3479

    
3480
     @property
3481
     def head(self):
3482
        """
3483
        head(self)
3484
        Property to get the first item in the sequence. This would be the PyXdmItem itself as there is only one item in the sequence
3485

    
3486
        Returns:
3487
            PyXdmItem: The PyXdmItem or None if the sequence is empty
3488

    
3489
        """
3490
        return self
3491

    
3492
     def get_atomic_value(self):
3493
        """
3494
        get_atomic_value(self)
3495
        Get the subclass PyXdmAtomicValue for this PyXdmItem object current object if it is an atomic value
3496
    
3497
        Returns:
3498
            PyXdmAtomicValue: Subclass this object to PyXdmAtomicValue or error 
3499
        """
3500
        if self.is_atomic == False:
3501
          raise Exception("The PyXdmItem is not an PyXdmAtomicValue")
3502
        val = PyXdmAtomicValue()
3503
        val.derivedaptr = val.derivedptr = <saxoncClasses.XdmAtomicValue*>self.derivedptr
3504
        val.derivedaptr.incrementRefCount()
3505
        return val
3506

    
3507
cdef class PyXdmNode(PyXdmItem):
3508
     cdef saxoncClasses.XdmNode *derivednptr      # hold a C++ instance which we're wrapping
3509

    
3510
     def __cinit__(self):
3511
        self.derivednptr = self.derivedptr = self.thisvptr = NULL
3512
    
3513
     def __dealloc__(self):
3514
        if type(self) is PyXdmNode and self.derivednptr != NULL:
3515
                 if self.derivednptr.getRefCount() < 1:
3516
                     del self.derivednptr
3517
                 else:
3518
                     self.derivednptr.decrementRefCount()
3519

    
3520
     @property
3521
     def head(self):
3522
        """
3523
        head(self)
3524
        Property to get the first item in the sequence. This would be the PyXdmNode itself as there is only one item in the sequence
3525

    
3526
        Returns:
3527
            PyXdmItem: The PyXdmItem or None if the sequence is empty
3528

    
3529
        """
3530
        return self
3531
                   
3532

    
3533
     @property
3534
     def node_kind(self):
3535
        """
3536
        node_kind(self)
3537
        Node Kind property. This will be a value such as {@link net.sf.saxon.type.Type#ELEMENT} or {@link net.sf.saxon.type.Type#ATTRIBUTE}.
3538
        There are seven kinds of node: documents, elements, attributes, text, comments, processing-instructions, and namespaces.
3539

    
3540
        Returns:
3541
            int: an integer identifying the kind of node. These integer values are the same as those used in the DOM 
3542
        """
3543
        cdef int kind
3544
        return self.derivednptr.getNodeKind()
3545

    
3546
     @property
3547
     def node_kind_str(self):
3548
        """
3549
        node_kind(self)
3550
        Node Kind property string. This will be a value such as {@link net.sf.saxon.type.Type#ELEMENT} or {@link net.sf.saxon.type.Type#ATTRIBUTE}.
3551
        There are seven kinds of node: documents, elements, attributes, text, comments, processing-instructions, and namespaces.
3552

    
3553
        Returns:
3554
            int: an integer identifying the kind of node. These integer values are the same as those used in the DOM 
3555
        """
3556
        cdef str kind
3557
        cdef int nk = self.derivednptr.getNodeKind()
3558
        if nk == DOCUMENT:
3559
            kind = 'document'
3560
        elif nk == ELEMENT:
3561
            kind = 'element'
3562
        elif nk == ATTRIBUTE:
3563
            kind = 'attribute'
3564
        elif nk == TEXT:
3565
            kind = 'text'
3566
        elif nk == COMMENT:
3567
            kind = 'comment'
3568
        elif nk == PROCESSING_INSTRUCTION:
3569
            kind = 'processing-instruction'
3570
        elif nk == NAMESPACE:
3571
            kind = 'namespace'
3572
        elif nk == UNKNOWN:
3573
            kind = 'unknown'
3574
        else:
3575
            raise ValueError('Unknown node kind: %d' % nk)
3576
        return kind
3577

    
3578
     @property
3579
     def name(self):
3580
        """
3581
        name(self)
3582
        Get the name of the node, as a string in the form of a EQName
3583
        Returns:
3584
            str: the name of the node. In the case of unnamed nodes (for example, text and comment nodes) return None       
3585
        """
3586
        cdef const char* c_string = self.derivednptr.getNodeName()
3587
        if c_string == NULL:
3588
            return None
3589
        else:
3590
            ustring = c_string.decode('UTF-8')
3591
            return ustring 
3592

    
3593
     @property
3594
     def typed_value(self):
3595
        """ 
3596
        typed_value(self)
3597
        Property - get the typed value of this node, as defined in XDM
3598
        Returns:
3599
            PyXdmValue:the typed value. If the typed value is a single atomic value, this will be returne as an instance of {@link XdmAtomicValue}                
3600
        """
3601
        cdef PyXdmValue val = None
3602
        cdef saxoncClasses.XdmValue * xdmValue = self.derivednptr.getTypedValue()
3603
        if xdmValue == NULL:
3604
            return None
3605
        else:
3606
            val = PyXdmValue()
3607
            val.thisvptr = xdmValue
3608
            return val
3609

    
3610
     @property
3611
     def base_uri(self):
3612
        """ 
3613
        base_uri(self)
3614
        Base uri Property. Get the Base URI for the node, that is, the URI used for resolving a relative URI contained in the node.
3615
        This will be the same as the System ID unless xml:base has been used. Where the node does not have a base URI of its own,
3616
        the base URI of its parent node is returned.
3617
        Returns:
3618
            str: String value of the base uri for this node. This may be NULL if the base URI is unknown, including the case
3619
                 where the node has no parent.
3620
        """
3621
        return make_py_str(self.derivednptr.getBaseUri())
3622

    
3623
     @property
3624
     def string_value(self):
3625
        """
3626
        get_String_value(self)
3627
        Property to get the string value of the node as defined in the XPath data model.
3628

    
3629
        Returns:
3630
            str: The string value of this node
3631

    
3632
        """
3633
        cdef const char* c_string = self.derivednptr.getStringValue()
3634
        ustring = c_string.decode('UTF-8') if c_string is not NULL else None
3635
        return ustring
3636

    
3637

    
3638
     def __str__(self):
3639
        """
3640
        __str__(self)
3641
        The string value of the node as defined in the XPath data model
3642
        Returns:
3643
            str: String value of this node
3644
        """
3645
        cdef const char* c_string = self.derivednptr.toString()
3646
        ustring = c_string.decode('UTF-8') if c_string is not NULL else None
3647
        return ustring
3648

    
3649
     def __repr__(self):
3650
        """
3651
        ___repr__ 
3652
        """
3653
        cdef const char* c_string = self.derivednptr.toString()
3654
        ustring = c_string.decode('UTF-8') if c_string is not NULL else None
3655
        return ustring
3656

    
3657

    
3658

    
3659
     def get_parent(self):
3660
        """
3661
        get_parent(self)
3662
        Get the current node's parent
3663

    
3664
        Returns:
3665
            PyXdmNode: The parent node as PyXdmNode object
3666
        """
3667

    
3668
        cdef PyXdmNode val = PyXdmNode()
3669
        val.derivednptr = val.derivedptr = val.thisvptr = self.derivednptr.getParent()
3670
        return val
3671

    
3672
     def get_attribute_value(self, name):
3673
        """
3674
        getAttribute_value(self, name)
3675
        The name of the required attribute
3676
        
3677
        Args:
3678
            name(str): the eqname of the required attribute
3679

    
3680
        """
3681
        py_value_string = name.encode('UTF-8') if name is not None else None
3682
        cdef char * c_name = py_value_string if name is not None else ""
3683
         
3684
        cdef const char* c_string = self.derivednptr.getAttributeValue(c_name)
3685
        ustring = c_string.decode('UTF-8') if c_string is not NULL else None
3686
                
3687
        return ustring
3688

    
3689
     @property
3690
     def attribute_count(self):
3691
        """
3692
        attribute_count(self)
3693
        Property to get the count of attribute nodes on this XdmNode object. If this current node is not an element node then return 0
3694

    
3695
        Returns:
3696
            int: Count of attribute nodes
3697

    
3698
        """
3699
        return self.derivednptr.getAttributeCount()
3700

    
3701
     @property
3702
     def attributes(self):
3703
        """
3704
        attribute_nodes(self)
3705
        Property to get the attribute nodes as a list of PyXdmNode objects
3706

    
3707
        Returns:
3708
            list[PyXdmNode]: List of PyXdmNode objects
3709
        """
3710
        cdef list nodes = []
3711
        cdef saxoncClasses.XdmNode **n
3712
        cdef int count, i
3713
        cdef PyXdmNode val = None
3714
        count = self.derivednptr.getAttributeCount()
3715
        if count > 0:
3716
            n = self.derivednptr.getAttributeNodes()
3717
            for i in range(count):
3718
                val = PyXdmNode()
3719
                val.derivednptr = val.derivedptr = val.thisvptr = n[i]
3720
                val.derivednptr.incrementRefCount()
3721
                nodes.append(val)
3722

    
3723
        return nodes
3724

    
3725

    
3726
     @property
3727
     def children(self):
3728
        """
3729
        children(self)
3730
        Property to get children of this current node. List of child nodes
3731

    
3732
        Returns:
3733
            list[PyXdmNode]: List of PyXdmNode objects
3734
        """
3735
        cdef list nodes = []
3736
        cdef saxoncClasses.XdmNode **n
3737
        cdef int count, i
3738
        cdef PyXdmNode val = None
3739
        count = self.derivednptr.getChildCount()
3740
        if count > 0:
3741
            n = self.derivednptr.getChildren()
3742
            for i in range(count):
3743
                val = PyXdmNode()
3744
                val.derivednptr = val.derivedptr = val.thisvptr = n[i]
3745
                val.derivednptr.incrementRefCount()
3746
                nodes.append(val)
3747

    
3748
        return nodes
3749

    
3750
      # def getChildCount(self):
3751

    
3752

    
3753
cdef class PyXdmAtomicValue(PyXdmItem):
3754
     """
3755
     The class PyXdmAtomicValue represents an item in an Xath sequence that is an atomic value. The value may belong to any of the
3756
     19 primitive types defined in XML Schema, or to a type derived from these primitive types, or the XPath type xs:untypedAtomic.
3757
     """
3758

    
3759
     cdef saxoncClasses.XdmAtomicValue *derivedaptr      # hold a C++ instance which we're wrapping
3760

    
3761
     def __cinit__(self):
3762
        if type(self) is PyXdmAtomicValue:
3763
            self.derivedaptr = self.derivedptr = self.thisvptr = new saxoncClasses.XdmAtomicValue()
3764
     def __dealloc__(self):
3765
        if self.derivedaptr != NULL and self.derivedaptr != NULL:
3766
            if self.derivedaptr.getRefCount() < 1:
3767
                del self.derivedaptr
3768
            else:
3769
                self.derivedaptr.decrementRefCount()
3770
            
3771

    
3772
     @property
3773
     def primitive_type_name(self):
3774
        """
3775
        get_primitive_type_name()
3776
        Property - Get the primitive type name of the PyXdmAtomicValue
3777
        Returns:
3778
            str: String of the primitive type name
3779

    
3780
        """      
3781
        cdef const char* c_string = self.derivedaptr.getPrimitiveTypeName()
3782
        ustring = c_string.decode('UTF-8')
3783
        return ustring
3784

    
3785

    
3786
     @property
3787
     def boolean_value(self):
3788
        """
3789
        Property which returns the boolean value of the PyXdmAtomicValue
3790

    
3791
        Returns:
3792
            bool: boolean value.
3793

    
3794

    
3795
        """
3796
        return self.derivedaptr.getBooleanValue()
3797

    
3798
     @property
3799
     def double_value(self):
3800
        """
3801
        Property which is returns the double value of the PyXdmAtomicValue if it can be converted.
3802

    
3803
        Returns:
3804
            double: Double value of the Xdm object
3805

    
3806
        """
3807
        
3808
        return self.derivedaptr.getDoubleValue()
3809

    
3810
     @property
3811
     def head(self):
3812
        """
3813
        head(self)
3814
        Property to get the first item in the sequence. This would be the PyXdmAtomicValue itself as there is only one item in the sequence
3815

    
3816
        Returns:
3817
            PyXdmAtomicValue: The PyXdmAtomic or None if the sequence is empty
3818

    
3819
        """
3820
        return self
3821
    
3822

    
3823
     @property
3824
     def integer_value(self):
3825
        """
3826
        Property which is returns the int value of the PyXdmAtomicValue if it can be converted.
3827

    
3828
        Returns:
3829
            int: Int value of the Xdm object
3830

    
3831
        """
3832
        
3833
        return self.derivedaptr.getLongValue()
3834

    
3835

    
3836
     @property
3837
     def string_value(self):
3838
        """
3839
        Property which returns the string value of the PyXdmAtomicValue
3840
        Returns:
3841
            str: String value of the Xdm object
3842
        """
3843
        cdef const char* c_string = self.derivedaptr.getStringValue()
3844
        ustring = c_string.decode('UTF-8')
3845
        return ustring
3846

    
3847

    
3848
     def __str__(self):
3849
        """
3850
        __str__(self)
3851
        The string value of the node as defined in the XPath data model
3852
        Returns:
3853
            str: String value of this node
3854
        """
3855
        cdef const char* c_string = self.derivedaptr.getStringValue()
3856
        ustring = c_string.decode('UTF-8')
3857
        return ustring
3858

    
3859
     def __repr__(self):
3860
        """
3861
        ___repr__ 
3862
        """
3863
        cdef const char* c_string = self.derivedaptr.getStringValue()
3864
        ustring = c_string.decode('UTF-8')
3865
        return ustring
3866

    
(8-8/11)