Project

Profile

Help

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

he / latest10 / hec / Saxon.C.API / python-saxon / test_saxonc.py @ 6304fb8b

1
from tempfile import mkstemp
2
import pytest
3
from saxonc import *
4
import os
5
from os.path import isfile
6

    
7

    
8
@pytest.fixture
9
def saxonproc():
10
    return PySaxonProcessor()
11

    
12

    
13
@pytest.fixture
14
def files_dir():
15
    return "../../samples/php"
16

    
17
@pytest.fixture
18
def data_dir():
19
    return "../../samples/data/"
20

    
21
def test_create_bool():
22
    """Create SaxonProcessor object with a boolean argument"""
23
    sp1 = PySaxonProcessor(True)
24
    sp2 = PySaxonProcessor(False)
25
    assert isinstance(sp1, PySaxonProcessor)
26
    assert isinstance(sp2, PySaxonProcessor)
27

    
28

    
29
'''@pytest.mark.skip('Error: SaxonDll.processor is nullptr in constructor(configFile)')'''
30
def test_create_config():
31
    """Create SaxonProcessor object with a configuration file argument"""
32
    conf_xml = b"""\
33
    <configuration xmlns="http://saxon.sf.net/ns/configuration" edition="HE">
34
    <global
35
        allowExternalFunctions="true"
36
        allowMultiThreading="true"
37
        allowOldJavaUriFormat="false"
38
        collationUriResolver="net.sf.saxon.lib.StandardCollationURIResolver"
39
        collectionUriResolver="net.sf.saxon.lib.StandardCollectionURIResolver"
40
        compileWithTracing="false"
41
       defaultCollation="http://www.w3.org/2005/xpath-functions/collation/codepoint"
42
       defaultCollection="file:///e:/temp"
43
        dtdValidation="false"
44
        dtdValidationRecoverable="true"
45
        errorListener="net.sf.saxon.StandardErrorListener"
46
        expandAttributeDefaults="true"
47
        lazyConstructionMode="false"
48
        lineNumbering="true"
49
        optimizationLevel="10"
50
        preEvaluateDocFunction="false"
51
        preferJaxpParser="true"
52
        recognizeUriQueryParameters="true"
53
        schemaValidation="strict"
54
        serializerFactory=""
55
        sourceParser=""
56
        sourceResolver=""
57
        stripWhitespace="all"
58
        styleParser=""
59
        timing="false"
60
        traceExternalFunctions="true"
61
        traceListener="net.sf.saxon.trace.XSLTTraceListener"
62
        traceOptimizerDecisions="false"
63
        treeModel="tinyTreeCondensed"
64
        uriResolver="net.sf.saxon.StandardURIResolver"
65
        usePiDisableOutputEscaping="false"
66
        useTypedValueCache="true"
67
        validationComments="false"
68
        validationWarnings="true"
69
        versionOfXml="1.0"
70
        xInclude="false"
71
      />
72
      <xslt
73
        initialMode=""
74
        initialTemplate=""
75
        messageReceiver=""
76
        outputUriResolver=""
77
        recoveryPolicy="recoverWithWarnings"
78
        schemaAware="false"
79
        staticErrorListener=""
80
        staticUriResolver=""
81
        styleParser=""
82
        version="2.1"
83
        versionWarning="false">
84
        <extensionElement namespace="http://saxon.sf.net/sql"
85
            factory="net.sf.saxon.option.sql.SQLElementFactory"/>
86
      </xslt>
87
      <xquery
88
        allowUpdate="true"
89
        constructionMode="preserve"
90
       defaultElementNamespace=""
91
       defaultFunctionNamespace="http://www.w3.org/2005/xpath-functions"
92
        emptyLeast="true"
93
        inheritNamespaces="true"
94
        moduleUriResolver="net.sf.saxon.query.StandardModuleURIResolver"
95
        preserveBoundarySpace="false"
96
        preserveNamespaces="true"
97
        requiredContextItemType="document-node()"
98
        schemaAware="false"
99
        staticErrorListener=""
100
        version="1.1"
101
        />
102
      <xsd
103
        occurrenceLimits="100,250"
104
        schemaUriResolver="com.saxonica.sdoc.StandardSchemaResolver"
105
        useXsiSchemaLocation="false"
106
        version="1.1"
107
      />
108
      <serialization
109
        method="xml"
110
        indent="yes"
111
        saxon:indent-spaces="8"
112
        xmlns:saxon="http://saxon.sf.net/"/>
113
      <localizationsdefaultLanguage="en"defaultCountry="US">
114
        <localization lang="da" class="net.sf.saxon.option.local.Numberer_da"/>
115
        <localization lang="de" class="net.sf.saxon.option.local.Numberer_de"/>
116
      </localizations>
117
      <resources>
118
        <externalObjectModel>net.sf.saxon.option.xom.XOMObjectModel</externalObjectModel>
119
        <extensionFunction>s9apitest.TestIntegrationFunctions$SqrtFunction</extensionFunction>
120
        <schemaDocument>file:///c:/MyJava/samples/data/books.xsd</schemaDocument>
121
        <schemaComponentModel/>
122
      </resources>
123
      <collations>
124
        <collation uri="http://www.w3.org/2005/xpath-functions/collation/codepoint"
125
                   class="net.sf.saxon.sort.CodepointCollator"/>
126
        <collation uri="http://www.microsoft.com/collation/caseblind"
127
                   class="net.sf.saxon.sort.CodepointCollator"/>
128
        <collation uri="http://example.com/french" lang="fr" ignore-case="yes"/>
129
      </collations>
130
    </configuration>
131
    """
132
    try:
133
        fd, fname = mkstemp(suffix='.xml')
134
        os.write(fd, conf_xml)
135
        os.close(fd)
136
        if not os.path.exists(fname):
137
            raise IOError('%s does not exist' % fname)
138

    
139
        with open(fname, 'r') as f:
140
            print(f.read())
141

    
142
        sp = SaxonProcessor(config_file=fname.encode('utf-8'))
143
        assert isinstance(sp, SaxonProcessor)
144
    finally:
145
        os.unlink(fname)
146

    
147

    
148
def test_create_procs():
149
    """Create XPathProcessor, XsltProcessor from SaxonProcessor object"""
150
    sp = PySaxonProcessor()
151
    xp = sp.new_xpath_processor()
152
    xsl = sp.new_xslt_processor()
153
    xsl30 = sp.new_xslt30_processor()
154
    assert isinstance(xp, PyXPathProcessor)
155
    assert isinstance(xsl, PyXsltProcessor)
156
    assert isinstance(xsl30, PyXslt30Processor)
157

    
158

    
159
def test_version():
160
    """SaxonProcessor version string content"""
161
    sp = PySaxonProcessor()
162
    ver = sp.version
163
    
164
    assert ver.startswith('Saxon/C ')
165
    assert ver.endswith('from Saxonica')
166

    
167
def test_schema_aware(saxonproc):
168

    
169
    assert saxonproc.is_schema_aware == False
170

    
171

    
172
def test_schema_aware2():
173
    ''' This unit test requires a valid license - Saxon-EE/C '''
174
    sp = PySaxonProcessor(license=True)
175
    assert sp.is_schema_aware == True
176

    
177

    
178
'''PyXsltProcessor test cases '''
179

    
180
def test_xslt_processor(data_dir):
181
    sp = PySaxonProcessor()
182
    xsltproc = sp.new_xslt_processor()
183
    xmlFile = data_dir + "cat.xml"
184
    node_ = sp.parse_xml(xml_file_name=xmlFile)
185
    xsltproc.set_source(xdm_node=node_)
186
    xsltproc.compile_stylesheet(stylesheet_text="<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='2.0'>       <xsl:param name='values' select='(2,3,4)' /><xsl:output method='xml' indent='yes' /><xsl:template match='*'><output><xsl:value-of select='//person[1]'/><xsl:for-each select='$values' ><out><xsl:value-of select='. * 3'/></out></xsl:for-each></output></xsl:template></xsl:stylesheet>")
187
    output2 = xsltproc.transform_to_string()
188
    assert 'text1' in output2
189

    
190
def test_Xslt_from_file(saxonproc, data_dir):
191
    xsltproc = saxonproc.new_xslt_processor()
192
    xmlFile = data_dir+'cat.xml'
193
    result = xsltproc.transform_to_string(source_file=data_dir+'cat.xml', stylesheet_file=data_dir+'test.xsl')
194
    assert result is not None
195
    assert 'text3' in result
196

    
197

    
198
def test_Xslt_from_file2(saxonproc, data_dir):
199
    xsltproc = saxonproc.new_xslt_processor()
200
    xmlFile = data_dir+'cat.xml'
201
    result = xsltproc.transform_to_string(source_file=data_dir+'cat.xml', stylesheet_file=data_dir+'test.xsl')
202
    assert result is not None
203
    assert 'text3' in result
204

    
205

    
206
def test_Xslt_from_file_error(saxonproc, data_dir):
207
    xsltproc = saxonproc.new_xslt_processor()
208
    result = xsltproc.transform_to_value(source_file=data_dir+'cat.xml', stylesheet_file=data_dir+'test-error.xsl')
209
    assert result is None
210
    assert xsltproc.exception_occurred()
211
    assert xsltproc.exception_count() == 1
212

    
213
def test_xslt_parameter(saxonproc, data_dir):
214
    input_ = saxonproc.parse_xml(xml_text="<out><person>text1</person><person>text2</person><person>text3</person></out>")
215
    value1 = saxonproc.make_integer_value(10)
216
    trans = saxonproc.new_xslt_processor()
217
    trans.set_parameter("numParam",value1)
218
    assert value1 is not None
219

    
220
    trans.set_source(xdm_node=input_)
221
    output_ = trans.transform_to_string(stylesheet_file=data_dir+"test.xsl")
222
    assert 'text2' in output_
223

    
224

    
225

    
226

    
227
'''PyXslt30Processor test cases '''
228

    
229
def testContextNotRoot(saxonproc):
230
    node = saxonproc.parse_xml(xml_text="<doc><e>text</e></doc>")
231
    trans = saxonproc.new_xslt30_processor()
232
    trans.compile_stylesheet(stylesheet_text="<xsl:stylesheet version='2.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'><xsl:variable name='x' select='.'/><xsl:template match='/'>errorA</xsl:template><xsl:template match='e'>[<xsl:value-of select='name($x)'/>]</xsl:template></xsl:stylesheet>")
233
    assert node is not None
234
    assert isinstance(node, PyXdmNode)
235
    assert len(node.children)>0
236
    eNode = node.children[0].children[0]
237
    assert eNode is not None
238
    trans.set_global_context_item(xdm_item=node)
239
    trans.set_initial_match_selection(xdm_value=eNode)
240
    result = trans.apply_templates_returning_string()
241
    assert result is not None
242
    assert "[" in result
243

    
244

    
245
def testResolveUri(saxonproc):
246
    trans = saxonproc.new_xslt30_processor()
247
    trans.compile_stylesheet(stylesheet_text="<xsl:stylesheet version='3.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:xs='http://www.w3.org/2001/XMLSchema' xmlns:err='http://www.w3.org/2005/xqt-errors'><xsl:template name='go'><xsl:try><xsl:variable name='uri' as='xs:anyURI' select=\"resolve-uri('notice trailing space /out.xml')\"/> <xsl:message select='$uri'/><xsl:result-document href='{$uri}'><out/></xsl:result-document><xsl:catch><xsl:sequence select=\"'\$err:code: ' || $err:code  || ', $err:description: ' || $err:description\"/></xsl:catch></xsl:try></xsl:template></xsl:stylesheet>")
248

    
249
    value = trans.call_template_returning_value("go")
250
    assert value is not None
251
    item = value.head
252
    assert "code" in item.string_value
253

    
254

    
255
def testEmbeddedStylesheet(saxonproc, data_dir):
256
    trans = saxonproc.new_xslt30_processor()
257
    input_ = saxonproc.parse_xml(xml_file_name=data_dir+"books.xml")
258
    path = "/processing-instruction(xml-stylesheet)[matches(.,'type\\s*=\\s*[''\"\"]text/xsl[''\" \"]')]/replace(., '.*?href\\s*=\\s*[''\" \"](.*?)[''\" \"].*', '$1')"
259

    
260
    print(data_dir+"books.xml")
261

    
262
    xPathProcessor = saxonproc.new_xpath_processor()
263
    xPathProcessor.set_context(xdm_item=input_)
264
    hrefval = xPathProcessor.evaluate_single(path)
265
    assert hrefval is not None
266
    href = hrefval.string_value
267
    print("href="+href)
268
    assert href != ""
269
    styles_dir = "../../samples/styles/"
270
    trans.compile_stylesheet(stylesheet_file=styles_dir+href)
271

    
272
    assert isinstance(input_, PyXdmNode)
273
    node = trans.transform_to_value(xdm_node=input_)
274
    assert node is not None
275

    
276
def testContextNotRootNamedTemplate(saxonproc, files_dir):
277

    
278
    trans = saxonproc.new_xslt30_processor()
279
    input_ = saxonproc.parse_xml(xml_text="<doc><e>text</e></doc>")
280
    trans.compile_stylesheet(stylesheet_text="<xsl:stylesheet version='2.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'><xsl:variable name='x' select='.'/><xsl:template match='/'>errorA</xsl:template><xsl:template name='main'>[<xsl:value-of select='name($x)'/>]</xsl:template></xsl:stylesheet>")      
281
    trans.set_global_context_item(xdm_item=input_)
282
    result = trans.call_template_returning_value("main")
283
    assert result is not None
284
    assert "[]" in result.head.string_value
285
    result2 = trans.call_template_returning_string("main")
286
    assert result2 is not None
287
    assert "[]" in result2
288

    
289

    
290
  
291
def testUseAssociated(saxonproc, files_dir):
292

    
293
    trans = saxonproc.new_xslt30_processor()
294
    foo_xml = files_dir+"/trax/xml/foo.xml"
295
    trans.compile_stylesheet(associated_file=foo_xml)
296
    trans.set_initial_match_selection(file_name=foo_xml)
297
    result = trans.apply_templates_returning_string()
298
    assert result is not None
299

    
300

    
301
def testnullptrStylesheet(saxonproc):
302

    
303
    trans = saxonproc.new_xslt30_processor()
304
    result = trans.apply_templates_returning_string()
305
    assert result is None
306

    
307

    
308
def testXdmDestination(saxonproc):
309
    trans = saxonproc.new_xslt30_processor()
310
    trans.compile_stylesheet(stylesheet_text="<xsl:stylesheet version='2.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'><xsl:template name='go'><a/></xsl:template></xsl:stylesheet>")
311

    
312
    root = trans.call_template_returning_value("go")
313
    assert root is not None
314
    assert root.head is not None
315
    assert root.head.is_atomic == False
316
    node  = root.head
317
    assert node is not None
318
    assert isinstance(node, PyXdmNode)
319
    assert node.node_kind == 9
320

    
321
def testXdmDestinationWithItemSeparator(saxonproc):
322
    trans = saxonproc.new_xslt30_processor()
323
    trans.compile_stylesheet(stylesheet_text="<xsl:stylesheet version='2.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'><xsl:template name='go'><xsl:comment>A</xsl:comment><out/><xsl:comment>Z</xsl:comment></xsl:template><xsl:output method='xml' item-separator='§'/></xsl:stylesheet>")
324

    
325
    root = trans.call_template_returning_value("go")
326
    node  = root
327
    
328
    assert "<!--A-->§<out/>§<!--Z-->" == node.__str__()
329
    assert node.node_kind == 9
330

    
331

    
332

    
333
def testPipeline(saxonproc):
334
    stage1 = saxonproc.new_xslt30_processor()        
335
    xsl = "<xsl:stylesheet version='2.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'><xsl:template match='/'><a><xsl:copy-of select='.'/></a></xsl:template></xsl:stylesheet>"
336
    xml = "<z/>"
337
    stage1.compile_stylesheet(stylesheet_text=xsl)
338
    in_ = saxonproc.parse_xml(xml_text=xml)
339

    
340
    stage2 = saxonproc.new_xslt30_processor()
341
    stage2.compile_stylesheet(stylesheet_text=xsl)
342
    stage3 = saxonproc.new_xslt30_processor()
343
    stage3.compile_stylesheet(stylesheet_text=xsl)
344
    stage4 = saxonproc.new_xslt30_processor()
345
    stage4.compile_stylesheet(stylesheet_text=xsl)
346

    
347
    stage5 = saxonproc.new_xslt30_processor()
348
    stage5.compile_stylesheet(stylesheet_text=xsl)
349
    assert in_ is not None
350
    stage1.set_property("!omit-xml-declaration", "yes")
351
    stage1.set_property("!indent", "no")
352
    stage1.set_initial_match_selection(xdm_value=in_)
353
    d1 = stage1.apply_templates_returning_value()
354

    
355
    assert d1 is not None    
356
    stage2.set_property("!omit-xml-declaration", "yes")
357
    stage2.set_property("!indent", "no")
358
    stage2.set_initial_match_selection(xdm_value=d1)
359
    d2 = stage2.apply_templates_returning_value()
360
    assert d2 is not None
361
    stage3.set_property("!omit-xml-declaration", "yes")
362
    stage3.set_property("!indent", "no")
363
    stage3.set_initial_match_selection(xdm_value=d2)
364
    d3 = stage3.apply_templates_returning_value()
365

    
366
    assert d3 is not None
367
    stage4.set_property("!omit-xml-declaration", "yes")
368
    stage4.set_property("!indent", "no")
369
    stage4.set_initial_match_selection(xdm_value=d3)
370
    d4 = stage4.apply_templates_returning_value()
371
    assert d3 is not None
372
    stage5.set_property("!indent", "no")
373
    stage5.set_property("!omit-xml-declaration", "yes")
374
    stage5.set_initial_match_selection(xdm_value=d4)
375
    sw = stage5.apply_templates_returning_string()
376
    assert sw is not None
377
    assert "<a><a><a><a><a><z/></a></a></a></a></a>" in sw
378

    
379

    
380
def testPipelineShort(saxonproc):
381
    
382
    xsl = "<xsl:stylesheet version='2.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'><xsl:template match='/'><a><xsl:copy-of select='.'/></a></xsl:template></xsl:stylesheet>"
383
    xml = "<z/>"
384
    stage1 = saxonproc.new_xslt30_processor()
385
    stage2 = saxonproc.new_xslt30_processor()
386

    
387
    stage1.compile_stylesheet(stylesheet_text=xsl)
388
    stage2.compile_stylesheet(stylesheet_text=xsl)
389

    
390
    stage1.set_property("!omit-xml-declaration", "yes")
391
    stage2.set_property("!omit-xml-declaration", "yes")
392
    in_ = saxonproc.parse_xml(xml_text=xml)
393
    assert in_ is not None
394
    stage1.set_initial_match_selection(xdm_value=in_)
395
    out = stage1.apply_templates_returning_value()
396
    assert out is not None
397
    stage2.set_initial_match_selection(xdm_value=out)
398
    sw = stage2.apply_templates_returning_string()
399
    assert "<a><a><z/></a></a>" in sw
400

    
401
def testCallFunction(saxonproc):
402
  
403
    source = "<?xml version='1.0'?><xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform'  xmlns:xs='http://www.w3.org/2001/XMLSchema'  xmlns:f='http://localhost/'  version='3.0'>  <xsl:function name='f:add' visibility='public'>    <xsl:param name='a'/><xsl:param name='b'/>   <xsl:sequence select='$a + $b'/></xsl:function>  </xsl:stylesheet>"
404
    trans = saxonproc.new_xslt30_processor()
405

    
406
    trans.compile_stylesheet(stylesheet_text=source)
407
    paramArr = [saxonproc.make_integer_value(2), saxonproc.make_integer_value(3)]
408
    v = trans.call_function_returning_value("{http://localhost/}add", paramArr)
409
    assert isinstance(v.head, PyXdmItem)
410
    assert v.head.is_atomic                
411
    assert v.head.get_atomic_value().integer_value ==5
412
    trans.clear_parameters()
413
        
414
  
415
def testCallFunctionArgConversion(saxonproc):
416
    trans = saxonproc.new_xslt30_processor()
417

    
418
    source = "<?xml version='1.0'?><xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform'  xmlns:xs='http://www.w3.org/2001/XMLSchema' xmlns:f='http://localhost/'  version='3.0'>  <xsl:function name='f:add' visibility='public'> <xsl:param name='a' as='xs:double'/>  <xsl:param name='b' as='xs:double'/>  <xsl:sequence select='$a + $b'/> </xsl:function> </xsl:stylesheet>"
419

    
420
    trans.compile_stylesheet(stylesheet_text=source)
421

    
422
    v = trans.call_function_returning_value("{http://localhost/}add", [saxonproc.make_integer_value(2), saxonproc.make_integer_value(3)])
423
    assert isinstance(v.head, PyXdmItem)
424
    assert v.head.is_atomic                
425
    assert v.head.get_atomic_value().double_value == 5.0e0
426
    ''' assert ("double", $v.head.get_atomic_value()->getPrimitiveTypeName()
427
    '''
428

    
429

    
430
def testCallFunctionWrapResults(saxonproc):
431
       
432
    trans = saxonproc.new_xslt30_processor()
433

    
434
    source = "<?xml version='1.0'?><xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:xs='http://www.w3.org/2001/XMLSchema'  xmlns:f='http://localhost/'  version='3.0'> <xsl:param name='x' as='xs:integer'/>  <xsl:param name='y' select='.+2'/>  <xsl:function name='f:add' visibility='public'>  <xsl:param name='a' as='xs:double'/> <xsl:param name='b' as='xs:double'/> <xsl:sequence select='$a + $b + $x + $y'/> </xsl:function> </xsl:stylesheet>"
435

    
436
    trans.compile_stylesheet(stylesheet_text=source)
437

    
438
    trans.set_property("!omit-xml-declaration", "yes")
439
    trans.set_parameter("x",  saxonproc.make_integer_value(30))
440
    trans.set_global_context_item(xdm_item=saxonproc.make_integer_value(20))
441

    
442
    sw = trans.call_function_returning_string("{http://localhost/}add", [saxonproc.make_integer_value(2), saxonproc.make_integer_value(3)])
443
    assert sw is not None
444
    assert "57" in sw
445
    trans.clear_parameters()
446
    
447

    
448

    
449

    
450
def testCallFunctionArgInvalid(saxonproc):
451
    trans = saxonproc.new_xslt30_processor()
452

    
453
    source = "<?xml version='1.0'?>  <xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:xs='http://www.w3.org/2001/XMLSchema' xmlns:f='http://localhost/'  version='2.0'><xsl:function name='f:add'> <xsl:param name='a' as='xs:double'/>  <xsl:param name='b' as='xs:double'/>  <xsl:sequence select='$a + $b'/> </xsl:function> </xsl:stylesheet>"
454

    
455
    trans.compile_stylesheet(stylesheet_text=source)
456
    argArr = [saxonproc.make_integer_value(2), saxonproc.make_integer_value(3)]
457
    v = trans.call_function_returning_value("{http://localhost/}add", argArr)
458
            
459
    assert trans.exception_count()==1
460
    assert "Cannot invoke function add#2 externally" in trans.get_error_message(0)
461
    assert v is None
462
    trans.clear_parameters()
463
    
464

    
465

    
466
def testCallNamedTemplateWithTunnelParams(saxonproc):
467
    trans = saxonproc.new_xslt30_processor()
468

    
469
    source = "<?xml version='1.0'?> <xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:xs='http://www.w3.org/2001/XMLSchema' version='3.0'>  <xsl:template name='t'> <xsl:call-template name='u'/>  </xsl:template>  <xsl:template name='u'> <xsl:param name='a' as='xs:double' tunnel='yes'/>  <xsl:param name='b' as='xs:float' tunnel='yes'/>   <xsl:sequence select='$a + $b'/> </xsl:template> </xsl:stylesheet>"
470

    
471
    trans.compile_stylesheet(stylesheet_text=source)
472
    trans.set_property("!omit-xml-declaration", "yes")
473
    trans.set_property("tunnel", "true")
474
    aVar = saxonproc.make_double_value(12)
475
    paramArr = {"a":aVar, "b":saxonproc.make_integer_value(5)}
476
    trans.set_initial_template_parameters(True, paramArr)
477
    sw = trans.call_template_returning_string("t")
478
    assert sw is not None
479
    assert "17" in sw
480
        
481

    
482
def testCallTemplateRuleWithParams(saxonproc):
483
    trans = saxonproc.new_xslt30_processor()
484

    
485
    source = "<?xml version='1.0'?> <xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:xs='http://www.w3.org/2001/XMLSchema'  version='3.0'> <xsl:template match='*'>  <xsl:param name='a' as='xs:double'/>  <xsl:param name='b' as='xs:float'/>  <xsl:sequence select='name(.), $a + $b'/> </xsl:template>  </xsl:stylesheet>"
486

    
487
    trans.compile_stylesheet(stylesheet_text=source)
488
    trans.set_property("!omit-xml-declaration", "yes")
489
    paramArr = {"a":saxonproc.make_integer_value(12), "b":saxonproc.make_integer_value(5)}
490
    trans.set_initial_template_parameters(False, paramArr)
491
    in_ = saxonproc.parse_xml(xml_text="<e/>")
492
    trans.set_initial_match_selection(xdm_value=in_)
493
    sw = trans.apply_templates_returning_string()
494
    sw is not None
495
    assert "e 17" in sw
496
   
497

    
498
def testApplyTemplatesToXdm(saxonproc):
499
    source = "<?xml version='1.0'?>  <xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform'  xmlns:xs='http://www.w3.org/2001/XMLSchema'  version='3.0'>  <xsl:template match='*'>     <xsl:param name='a' as='xs:double'/>     <xsl:param name='b' as='xs:float'/>     <xsl:sequence select='., $a + $b'/>  </xsl:template>  </xsl:stylesheet>"
500
    trans = saxonproc.new_xslt30_processor()
501
    trans.compile_stylesheet(stylesheet_text=source)
502
    trans.set_property("!omit-xml-declaration", "yes")
503
    paramArr = {"a":saxonproc.make_integer_value(12), "b":saxonproc.make_integer_value(5)}
504
    trans.set_initial_template_parameters(False, paramArr)
505
    trans.set_result_as_raw_value(True)
506
    in_put = saxonproc.parse_xml(xml_text="<e/>")
507
    trans.set_initial_match_selection(xdm_value=in_put)
508
    result = trans.apply_templates_returning_value()
509
    assert result is not None
510
    assert result.size == 2
511
    first = result.item_at(0)
512
    assert first.is_atomic == False
513
    assert "e" in first.get_node_value().name
514
    second = result.item_at(1)
515
    assert second.is_atomic            
516
    assert second.get_atomic_value().double_value == 17.0
517

    
518

    
519
def testItemAtDownCast(saxonproc):
520
    source = "<?xml version='1.0'?>  <xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform'  xmlns:xs='http://www.w3.org/2001/XMLSchema'  version='3.0'>  <xsl:template match='*'>     <xsl:param name='a' as='xs:double'/>     <xsl:param name='b' as='xs:float'/>     <xsl:sequence select='., $a + $b'/>  </xsl:template>  </xsl:stylesheet>"
521
    trans = saxonproc.new_xslt30_processor()
522
    trans.compile_stylesheet(stylesheet_text=source)
523
    trans.set_property("!omit-xml-declaration", "yes")
524
    paramArr = {"a":saxonproc.make_integer_value(12), "b":saxonproc.make_integer_value(5)}
525
    trans.set_initial_template_parameters(False, paramArr)
526
    trans.set_result_as_raw_value(True)
527
    in_put = saxonproc.parse_xml(xml_text="<e/>")
528
    trans.set_initial_match_selection(xdm_value=in_put)
529
    result = trans.apply_templates_returning_value()
530
    assert result is not None
531
    assert result.size == 2
532
    first = result.item_at(0)
533
    assert first.is_atomic == False
534
    assert isinstance(first, PyXdmNode)
535
    assert "e" in first.name
536
    second = result.item_at(1)
537
    assert isinstance(second, PyXdmAtomic)
538
    assert second.double_value == 17.0
539
    
540

    
541

    
542
def testResultDocument(saxonproc):
543
    xsl = "<xsl:stylesheet version='3.0'  xmlns:xsl='http://www.w3.org/1999/XSL/Transform'> <xsl:template match='a'>   <c>d</c> </xsl:template> <xsl:template match='whatever'>   <xsl:result-document href='out.xml'>     <e>f</e>   </xsl:result-document> </xsl:template></xsl:stylesheet>"
544
    trans = saxonproc.new_xslt30_processor()
545
    trans.compile_stylesheet(stylesheet_text=xsl)
546
    in_put = saxonproc.parse_xml(xml_text="<a>b</a>")
547
    trans.set_initial_match_selection(xdm_value=in_put)
548
    xdmValue = trans.apply_templates_returning_value()
549

    
550
    assert xdmValue.size == 1
551
    
552

    
553

    
554

    
555

    
556
def testApplyTemplatesToFile(saxonproc):
557

    
558
    xsl = "<xsl:stylesheet version='3.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>  <xsl:template match='a'> <c>d</c>  </xsl:template></xsl:stylesheet>"
559
    trans = saxonproc.new_xslt30_processor()
560
    trans.compile_stylesheet(stylesheet_text=xsl)
561
    in_put = saxonproc.parse_xml(xml_text="<a>b</a>")
562
    trans.set_output_file("output123.xml")
563
    trans.set_initial_match_selection(xdm_value=in_put)
564
    trans.apply_templates_returning_file(output_file="output123.xml")
565
    assert isfile("output123.xml") == True
566

    
567

    
568
'''@pytest.mark.skip('Test can only run with a license file present')'''
569
def testCallTemplateWithResultValidation(files_dir):
570
    saxonproc2 =  PySaxonProcessor(True)
571
    saxonproc2.set_cwd(files_dir)
572
    trans = saxonproc2.new_xslt30_processor()
573

    
574
    source = "<?xml version='1.0'?>  <xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform'  xmlns:xs='http://www.w3.org/2001/XMLSchema'  version='3.0' exclude-result-prefixes='#all'>  <xsl:import-schema><xs:schema><xs:element name='x' type='xs:int'/></xs:schema></xsl:import-schema>  <xsl:template name='main'>     <xsl:result-document validation='strict'>       <x>3</x>     </xsl:result-document>  </xsl:template>  </xsl:stylesheet>"
575

    
576
    trans.compile_stylesheet(stylesheet_text=source)
577
    trans.set_property("!omit-xml-declaration", "yes")
578
    sw = trans.call_template_returning_string("main")
579
    assert sw is not None 
580
    assert "<x>3</x>" == sw
581
     
582

    
583

    
584

    
585
def testCallTemplateNoParamsRaw(saxonproc):
586
    trans = saxonproc.new_xslt30_processor()
587
    trans.compile_stylesheet(stylesheet_text="<xsl:stylesheet version='2.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'><xsl:template name='xsl:initial-template'><xsl:sequence select='42'/></xsl:template></xsl:stylesheet>")
588

    
589
    trans.set_result_as_raw_value(True)
590
    result = trans.call_template_returning_value()
591
    assert result is not None
592
    assert result.head is not None
593
    assert result.head.is_atomic == True
594
    assert result.head.get_atomic_value().integer_value == 42
595
        
596

    
597

    
598

    
599
def testCallNamedTemplateWithParamsRaw(saxonproc):
600
    trans = saxonproc.new_xslt30_processor()
601

    
602
    source = "<?xml version='1.0'?>  <xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform'  xmlns:xs='http://www.w3.org/2001/XMLSchema'  version='3.0'>  <xsl:template name='t'>     <xsl:param name='a' as='xs:double'/>     <xsl:param name='b' as='xs:float'/>     <xsl:sequence select='$a+1, $b+1'/>  </xsl:template>  </xsl:stylesheet>"
603

    
604
    trans.compile_stylesheet(stylesheet_text=source)
605
    trans.set_result_as_raw_value(True)
606
    paramArr = {"a":saxonproc.make_integer_value(12), "b":saxonproc.make_integer_value(5)}
607
    trans.set_initial_template_parameters(False, paramArr)
608
    val = trans.call_template_returning_value("t")
609
    assert val is not None
610
    assert val.size == 2
611
    assert val.item_at(0).is_atomic
612
    assert val.item_at(0).get_atomic_value().integer_value == 13
613
    assert val.item_at(1).get_atomic_value().integer_value == 6
614
       
615

    
616
def testApplyTemplatesRaw(saxonproc):
617
    trans = saxonproc.new_xslt30_processor()
618

    
619
    source = "<?xml version='1.0'?>  <xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform'  xmlns:xs='http://www.w3.org/2001/XMLSchema'  version='3.0'>  <xsl:template match='*'>     <xsl:param name='a' as='xs:double'/>     <xsl:param name='b' as='xs:float'/>     <xsl:sequence select='., $a + $b'/>  </xsl:template>  </xsl:stylesheet>"
620

    
621
    trans.compile_stylesheet(stylesheet_text=source)
622
    node = saxonproc.parse_xml(xml_text="<e/>")
623

    
624
    trans.set_result_as_raw_value(True)
625
    paramArr = {"a":saxonproc.make_integer_value(12), "b":saxonproc.make_integer_value(5)}
626
    trans.set_initial_template_parameters(False, paramArr)
627
    trans.set_initial_match_selection(xdm_value=node)
628
    result = trans.apply_templates_returning_value()
629
    assert result is not None
630
    assert result.size ==2
631
    first = result.item_at(0)
632
    assert first is not None
633
    assert first.is_atomic == False
634
    assert first.get_node_value().name == "e"
635
    second = result.item_at(1)
636
    assert second is not None
637
    assert second.is_atomic
638
    assert second.get_atomic_value().double_value == 17.0
639
        
640

    
641

    
642
def testApplyTemplatesToSerializer(saxonproc):
643
    trans = saxonproc.new_xslt30_processor()
644

    
645
    source = "<?xml version='1.0'?>  <xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform'  xmlns:xs='http://www.w3.org/2001/XMLSchema'  version='3.0'>  <xsl:output method='text' item-separator='~~'/>  <xsl:template match='.'>     <xsl:param name='a' as='xs:double'/>     <xsl:param name='b' as='xs:float'/>     <xsl:sequence select='., $a + $b'/>  </xsl:template>  </xsl:stylesheet>"
646

    
647
    trans.compile_stylesheet(stylesheet_text=source)
648
    trans.set_property("!omit-xml-declaration", "yes")
649
    trans.set_result_as_raw_value(True)
650
    paramArr = {"a":saxonproc.make_integer_value(12), "b":saxonproc.make_integer_value(5)}
651
    trans.set_initial_template_parameters(False, paramArr)
652
  
653
    trans.set_initial_match_selection(xdm_value=saxonproc.make_integer_value(16))
654
    sw = trans.apply_templates_returning_string()
655

    
656
    assert "16~~17" == sw
657
 
658

    
659

    
660
    
661
''' PyXQueryProcessor '''
662

    
663
def test_return_document_node(saxonproc):
664
    node = saxonproc.parse_xml(xml_text='<foo/>')
665
    xqc = saxonproc.new_xquery_processor()
666
    xqc.set_query_content('document{.}')
667
    xqc.set_context(xdm_item=node)
668
    result = xqc.run_query_to_value()
669
    if isinstance(result, PyXdmNode):
670
        assert result.node_kind == DOCUMENT
671

    
672
def testxQuery1(saxonproc, data_dir):
673
    query_proc = saxonproc.new_xquery_processor()
674
    query_proc.clear_properties()
675
    query_proc.clear_parameters()
676
    xmlFile = data_dir+"cat.xml"
677
    query_proc.set_property("s", xmlFile)
678

    
679
    query_proc.set_property("qs", "<out>{count(/out/person)}</out>")
680

    
681
    result = query_proc.run_query_to_string()
682
    assert not result == None
683

    
684
    query_proc.set_cwd(".")
685
    query_proc.run_query_to_file(output_file_name="catOutput.xml")
686
    assert os.path.exists("catOutput.xml")
687
    node = saxonproc.parse_xml(xml_file_name='catOutput.xml')
688
    xp = saxonproc.new_xpath_processor()
689
    xp.set_context(xdm_item=node)
690
    assert xp.effective_boolean_value("/out/text()=3")    
691
    if os.path.exists('catOutput.xml'):
692
        os.remove("catOutput.xml")
693

    
694

    
695
def test_default_namespace(saxonproc):
696
    query_proc = saxonproc.new_xquery_processor()
697
    query_proc.declare_namespace("", "http://one.uri/")
698
    node = saxonproc.parse_xml(xml_text="<foo xmlns='http://one.uri/'><bar/></foo>")
699
    query_proc.set_context(xdm_item=node)
700
    query_proc.set_query_content("/foo")
701

    
702
    value = query_proc.run_query_to_value()
703

    
704
    assert value.size == 1 
705

    
706

    
707
def test_XQuery_line_number():
708
    ''' No license file given therefore result will return None'''
709
    proc = PySaxonProcessor(True)
710
    proc.set_configuration_property("l", "on")
711
    query_proc = proc.new_xquery_processor()
712
    
713
    query_proc.set_property("s", "cat.xml")
714
    query_proc.declare_namespace("saxon","http://saxon.sf.net/")
715

    
716
    query_proc.set_property("qs", "saxon:line-number(doc('cat.xml')/out/person[1])")
717

    
718
    result = query_proc.run_query_to_string()
719
    assert result == None
720
    
721

    
722
def testReusability(saxonproc):
723
    queryproc = saxonproc.new_xquery_processor()
724
    queryproc.clear_properties()
725
    queryproc.clear_parameters()
726

    
727
    input_ =  saxonproc.parse_xml(xml_text="<foo xmlns='http://one.uri/'><bar xmlns='http://two.uri'>12</bar></foo>")
728
    queryproc.declare_namespace("", "http://one.uri/")
729
    queryproc.set_query_content("declare variable $p as xs:boolean external; exists(/foo) = $p")
730

    
731
    queryproc.set_context(xdm_item=input_)
732

    
733
    value1 = saxonproc.make_boolean_value(True)
734
    queryproc.set_parameter("p",value1)
735
    result = queryproc.run_query_to_value()
736
       
737
    assert result is not None
738
    assert result.is_atomic
739
    assert result.boolean_value
740

    
741
    queryproc.clear_parameters()
742
    queryproc.clear_properties()    
743
    
744
    queryproc.declare_namespace("", "http://two.uri")
745
    queryproc.set_query_content("declare variable $p as xs:integer external; /*/bar + $p")
746
    
747
    queryproc.set_context(xdm_item=input_)
748

    
749
    value2 = saxonproc.make_long_value(6)
750
    queryproc.set_parameter("p",value2)
751
        
752
    result2 = queryproc.run_query_to_value()
753
    assert result2.integer_value == 18
754

    
755
def test_make_string_value(saxonproc):
756

    
757
    xdm_string_value = saxonproc.make_string_value('text1')
758
    
759
    print(xdm_string_value)
760

    
761
    xquery_processor = saxonproc.new_xquery_processor()
762

    
763
    xquery_processor.set_parameter('s1', xdm_string_value)
764

    
765
    result = xquery_processor.run_query_to_value(query_text = 'declare variable $s1 external; $s1')
766

    
767
    assert result is not None
768
    assert isinstance(result, PyXdmAtomicValue)
769
    assert result.string_value == "text1"
770

    
771

    
772

    
773
'''PyXPathProcessor test cases'''
774

    
775

    
776
def test_xpath_proc(saxonproc, data_dir):
777

    
778
    sp = saxonproc
779
    xp = saxonproc.new_xpath_processor()
780
    xmlFile = data_dir+"cat.xml"
781
    assert isfile(xmlFile)
782
    xp.set_context(file_name=xmlFile)
783
    assert xp.effective_boolean_value('count(//person) = 3')
784
    assert not xp.effective_boolean_value("/out/person/text() = 'text'")
785

    
786

    
787
def test_atomic_values():
788
    sp = PySaxonProcessor()
789
    value = sp.make_double_value(3.5)
790
    boolVal = value.boolean_value
791
    assert boolVal == True
792
    assert value.string_value == '3.5'
793
    assert value.double_value == 3.5
794
    assert value.integer_value == 3
795
    primValue = value.primitive_type_name
796
    assert primValue == 'Q{http://www.w3.org/2001/XMLSchema}double'
797

    
798

    
799
def test_node_list():
800
    xml = """\
801
    <out>
802
        <person att1='value1' att2='value2'>text1</person>
803
        <person>text2</person>
804
        <person>text3</person>
805
    </out>
806
    """
807
    sp = PySaxonProcessor()
808
    
809
    node = sp.parse_xml(xml_text=xml)
810
    outNode = node.children[0]
811
    children = outNode.children
812
    personData = str(children)    
813
    assert ('<person att1' in personData)
814

    
815

    
816

    
817
def parse_xml_file():
818

    
819
    sp = PySaxonProcessor()
820
    
821
    node = sp.parse_xml(xml_file_name='cat.xml')
822
    outNode = node.children[0]
823
    assert outNode.name == 'out'
824

    
825

    
826
def test_node():
827
    xml = """\
828
    <out>
829
        <person att1='value1' att2='value2'>text1</person>
830
        <person>text2</person>
831
        <person>text3</person>
832
    </out>
833
    """
834
    sp = PySaxonProcessor()
835
    
836
    node = sp.parse_xml(xml_text=xml)
837
    assert node.node_kind == 9    
838
    assert node.size == 1
839
    outNode = node.children[0]
840
    assert outNode.name == 'out'
841
    assert outNode.node_kind == ELEMENT
842
    children = outNode.children    
843
    attrs = children[1].attributes
844
    assert len(attrs) == 2
845
    assert children[1].get_attribute_value('att2') == 'value2'
846
    assert 'value2' in attrs[1].string_value 
847

    
848

    
849
def test_evaluate():
850
    xml = """\
851
    <out>
852
        <person att1='value1' att2='value2'>text1</person>
853
        <person>text2</person>
854
        <person>text3</person>
855
    </out>
856
    """
857
    sp = PySaxonProcessor()
858
    xp = sp.new_xpath_processor()
859
    
860
    node = sp.parse_xml(xml_text=xml)
861
    assert isinstance(node, PyXdmNode)
862
    xp.set_context(xdm_item=node)
863
    value = xp.evaluate('//person')
864
    assert isinstance(value, PyXdmValue)
865
    assert value.size == 3
866
    
867

    
868
def test_single():
869
    xml = """\
870
    <out>
871
        <person>text1</person>
872
        <person>text2</person>
873
        <person>text3</person>
874
    </out>
875
    """
876
    sp = PySaxonProcessor()
877
    xp = sp.new_xpath_processor()
878
    
879
    node = sp.parse_xml(xml_text=xml)
880
    assert isinstance(node, PyXdmNode)
881
    xp.set_context(xdm_item=node)
882
    item = xp.evaluate_single('//person[1]')
883
    assert isinstance(item, PyXdmItem)
884
    assert item.size == 1
885
    assert not item.is_atomic
886
    assert item.__str__() == '<person>text1</person>'
887

    
888
def test_declare_variable_value(saxonproc):
889
    s1 = 'This is a test.'
890
    xdm_string_value = saxonproc.make_string_value(s1)
891

    
892
    xpath_processor = saxonproc.new_xpath_processor()
893
    xpath_processor.set_parameter('s1', xdm_string_value)
894
    result = xpath_processor.evaluate('$s1')
895

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

    
899

    
900
def test_declare_variable_value2(saxonproc):
901
    s1 = 'This is a test.'
902
    xdm_string_value = saxonproc.make_string_value(s1)
903

    
904
    xpath_processor = saxonproc.new_xpath_processor()
905
    result = xpath_processor.evaluate('$s1')
906

    
907
    assert result is None
908

    
909
def test_packages(saxonproc):
910
    xsl = """\
911
    <xsl:package name = \"package-002.xsl\" package-version = \"2.1.0.5\"
912
    version = \"3.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">
913
    <xsl:param name='c' select='2'/>
914
    <xsl:mode/>
915
    <xsl:template match='/'>
916
    <out><xsl:apply-templates/></out>
917
    </xsl:template>
918
    <xsl:template match='/*'>
919
    <in><xsl:value-of select='name()'/></in>
920
    </xsl:template>
921
    </xsl:package>
922
    """
923
    xsltproc = saxonproc.new_xslt30_processor()
924
    xsltproc.compile_stylesheet(stylesheet_text=xsl, save=True, output_file='package02.xsltpack')
925
    xsltproc = None
926
    xsltproc2 = saxonproc.new_xslt30_processor()
927
    xsltproc2.transform_to_string(source_file=data_dir+"books.xml", stylesheet_file="package02.xsltpack")
928

    
929
def test_add_packages():
930
    sp = SaxonProcessor(config_file=data_dir+"config_file.xml")
931
    assert isinstance(sp, SaxonProcessor)
932
    xsl = sp.new_xslt30_processor()
933
    result = xsl.transform_to_string(source_file=data_dir+"package-00.xml", stylesheet_file=data_dir+"package-019.xsl")
934
    assert 'You found me!' in result
935

    
936

    
937
'''Test case should be run last to test release() '''
938
def test_release():
939
    with PySaxonProcessor(license=False) as proc:
940
        xsltproc = proc.new_xslt_processor()
941
        document = proc.parse_xml(xml_text="<out><person>text1</person><person>text2</person><person>text3</person></out>")
942
        xsltproc.set_source(xdm_node=document)
943
        xsltproc.compile_stylesheet(stylesheet_text="<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='2.0'>       <xsl:param name='values' select='(2,3,4)' /><xsl:output method='xml' indent='yes' /><xsl:template match='*'><output><xsl:value-of select='//person[1]'/><xsl:for-each select='$values' ><out><xsl:value-of select='. * 3'/></out></xsl:for-each></output></xsl:template></xsl:stylesheet>")
944
        output2 = xsltproc.transform_to_string()
945
        assert output2.startswith('<?xml version="1.0" encoding="UTF-8"?>\n<output>text1<out>6</out')
946

    
947
def release(saxonproc):
948
   saxonproc.release()
949

    
(11-11/11)