Mercurial > bitten > bitten-test
annotate bitten/build/xmltools.py @ 908:56c269e75737 0.6.x
Ported r989 back to 0.6.x branch.
author | cmlenz |
---|---|
date | Wed, 13 Apr 2011 13:25:27 +0000 |
parents | f4d07544722b |
children |
rev | line source |
---|---|
379 | 1 # -*- coding: utf-8 -*- |
243
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
2 # |
408
933105ab516b
Update file headers and other stuff pointing to the old home.
cmlenz
parents:
379
diff
changeset
|
3 # Copyright (C) 2005-2007 Christopher Lenz <cmlenz@gmx.de> |
833 | 4 # Copyright (C) 2007-2010 Edgewall Software |
243
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
5 # All rights reserved. |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
6 # |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
7 # This software is licensed as described in the file COPYING, which |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
8 # you should have received as part of this distribution. The terms |
408
933105ab516b
Update file headers and other stuff pointing to the old home.
cmlenz
parents:
379
diff
changeset
|
9 # are also available at http://bitten.edgewall.org/wiki/License. |
243
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
10 |
313 | 11 """Recipe commands for XML processing.""" |
12 | |
243
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
13 import logging |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
14 import os |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
15 |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
16 try: |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
17 import libxml2 |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
18 import libxslt |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
19 have_libxslt = True |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
20 except ImportError: |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
21 have_libxslt = False |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
22 |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
23 if not have_libxslt and os.name == 'nt': |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
24 try: |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
25 import win32com.client |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
26 have_msxml = True |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
27 except ImportError: |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
28 have_msxml = False |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
29 else: |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
30 have_msxml = False |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
31 |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
32 log = logging.getLogger('bitten.build.xmltools') |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
33 |
411
a169d2e96463
Use reStructuredText as the API documentation syntax.
cmlenz
parents:
408
diff
changeset
|
34 __docformat__ = 'restructuredtext en' |
a169d2e96463
Use reStructuredText as the API documentation syntax.
cmlenz
parents:
408
diff
changeset
|
35 |
243
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
36 def transform(ctxt, src=None, dest=None, stylesheet=None): |
313 | 37 """Apply an XSLT stylesheet to a source XML document. |
38 | |
39 This command requires either libxslt (with Python bindings), or MSXML to | |
40 be installed. | |
41 | |
411
a169d2e96463
Use reStructuredText as the API documentation syntax.
cmlenz
parents:
408
diff
changeset
|
42 :param ctxt: the build context |
a169d2e96463
Use reStructuredText as the API documentation syntax.
cmlenz
parents:
408
diff
changeset
|
43 :type ctxt: `Context` |
a169d2e96463
Use reStructuredText as the API documentation syntax.
cmlenz
parents:
408
diff
changeset
|
44 :param src: name of the XML input file |
a169d2e96463
Use reStructuredText as the API documentation syntax.
cmlenz
parents:
408
diff
changeset
|
45 :param dest: name of the XML output file |
a169d2e96463
Use reStructuredText as the API documentation syntax.
cmlenz
parents:
408
diff
changeset
|
46 :param stylesheet: name of the file containing the XSLT stylesheet |
313 | 47 """ |
243
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
48 assert src, 'Missing required attribute "src"' |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
49 assert dest, 'Missing required attribute "dest"' |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
50 assert stylesheet, 'Missing required attribute "stylesheet"' |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
51 |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
52 if have_libxslt: |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
53 log.debug('Using libxslt for XSLT transformation') |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
54 srcdoc, styledoc, result = None, None, None |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
55 try: |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
56 srcdoc = libxml2.parseFile(ctxt.resolve(src)) |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
57 styledoc = libxslt.parseStylesheetFile(ctxt.resolve(stylesheet)) |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
58 result = styledoc.applyStylesheet(srcdoc, None) |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
59 styledoc.saveResultToFilename(ctxt.resolve(dest), result, 0) |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
60 finally: |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
61 if styledoc: |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
62 styledoc.freeStylesheet() |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
63 if srcdoc: |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
64 srcdoc.freeDoc() |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
65 if result: |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
66 result.freeDoc() |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
67 |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
68 elif have_msxml: |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
69 log.debug('Using MSXML for XSLT transformation') |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
70 srcdoc = win32com.client.Dispatch('MSXML2.DOMDocument.3.0') |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
71 if not srcdoc.load(ctxt.resolve(src)): |
514 | 72 err = srcdoc.parseError |
908 | 73 ctxt.error('Failed to parse XML source %s: %s' % (src, err.reason)) |
243
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
74 return |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
75 styledoc = win32com.client.Dispatch('MSXML2.DOMDocument.3.0') |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
76 if not styledoc.load(ctxt.resolve(stylesheet)): |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
77 err = styledoc.parseError |
908 | 78 ctxt.error('Failed to parse XSLT stylesheet %s: %s' % |
79 (stylesheet, err.reason)) | |
243
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
80 return |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
81 result = srcdoc.transformNode(styledoc) |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
82 |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
83 # MSXML seems to always write produce the resulting XML document using |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
84 # UTF-16 encoding, regardless of the encoding specified in the |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
85 # stylesheet. For better interoperability, recode to UTF-8 here. |
248 | 86 result = result.encode('utf-8').replace(' encoding="UTF-16"?>', '?>') |
243
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
87 |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
88 dest_file = file(ctxt.resolve(dest), 'w') |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
89 try: |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
90 dest_file.write(result) |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
91 finally: |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
92 dest_file.close() |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
93 |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
94 else: |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
95 ctxt.error('No usable XSLT implementation found') |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
96 |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
97 # TODO: as a last resort, try to invoke 'xsltproc' to do the |
e75816cb2f45
* Add an <x:transform/> task for applying XSLT transformations. Can use either libxslt or MSXML if available. Closes #35.
cmlenz
parents:
diff
changeset
|
98 # transformation? |