XSLT as a filter and with parameters
This commit is contained in:
parent
db79be60cc
commit
21864c3aa8
@ -32,7 +32,7 @@ from urlparse import urljoin
|
|||||||
|
|
||||||
parser = ConfigParser()
|
parser = ConfigParser()
|
||||||
|
|
||||||
planet_predefined_options = []
|
planet_predefined_options = ['filters']
|
||||||
|
|
||||||
def __init__():
|
def __init__():
|
||||||
"""define the struture of an ini file"""
|
"""define the struture of an ini file"""
|
||||||
|
@ -1,5 +1,19 @@
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
|
def quote(string, apos):
|
||||||
|
""" quote a string so that it can be passed as a parameter """
|
||||||
|
if type(string) == unicode:
|
||||||
|
string=string.encode('utf-8')
|
||||||
|
if apos.startswith("\\"): string.replace('\\','\\\\')
|
||||||
|
|
||||||
|
if string.find("'")<0:
|
||||||
|
return "'" + string + "'"
|
||||||
|
elif string.find("'")<0:
|
||||||
|
return '"' + string + '"'
|
||||||
|
else:
|
||||||
|
# unclear how to quote strings with both types of quotes for libxslt
|
||||||
|
return "'" + string.replace("'",apos) + "'"
|
||||||
|
|
||||||
def run(script, doc, output_file=None, options={}):
|
def run(script, doc, output_file=None, options={}):
|
||||||
""" process an XSLT stylesheet """
|
""" process an XSLT stylesheet """
|
||||||
|
|
||||||
@ -12,6 +26,22 @@ def run(script, doc, output_file=None, options={}):
|
|||||||
except:
|
except:
|
||||||
# otherwise, use the command line interface
|
# otherwise, use the command line interface
|
||||||
dom = None
|
dom = None
|
||||||
|
|
||||||
|
# do it
|
||||||
|
result = None
|
||||||
|
if dom:
|
||||||
|
styledoc = libxml2.parseFile(script)
|
||||||
|
style = libxslt.parseStylesheetDoc(styledoc)
|
||||||
|
for key in options.keys():
|
||||||
|
options[key] = quote(options[key], apos="\xe2\x80\x99")
|
||||||
|
output = style.applyStylesheet(dom, options)
|
||||||
|
if output_file:
|
||||||
|
style.saveResultToFilename(output_file, output, 0)
|
||||||
|
else:
|
||||||
|
result = str(output)
|
||||||
|
style.freeStylesheet()
|
||||||
|
output.freeDoc()
|
||||||
|
elif output_file:
|
||||||
import warnings
|
import warnings
|
||||||
if hasattr(warnings, 'simplefilter'):
|
if hasattr(warnings, 'simplefilter'):
|
||||||
warnings.simplefilter('ignore', RuntimeWarning)
|
warnings.simplefilter('ignore', RuntimeWarning)
|
||||||
@ -20,16 +50,28 @@ def run(script, doc, output_file=None, options={}):
|
|||||||
file.write(doc)
|
file.write(doc)
|
||||||
file.close()
|
file.close()
|
||||||
|
|
||||||
# do it
|
cmdopts = []
|
||||||
if dom:
|
for key,value in options.items():
|
||||||
styledoc = libxml2.parseFile(script)
|
cmdopts += ['--stringparam', key, quote(value, apos=r"\'")]
|
||||||
style = libxslt.parseStylesheetDoc(styledoc)
|
|
||||||
result = style.applyStylesheet(dom, None)
|
os.system('xsltproc %s %s %s > %s' %
|
||||||
style.saveResultToFilename(output_file, result, 0)
|
(script, ' '.join(cmdopts), docfile, output_file))
|
||||||
style.freeStylesheet()
|
os.unlink(docfile)
|
||||||
result.freeDoc()
|
|
||||||
else:
|
else:
|
||||||
os.system('xsltproc %s %s > %s' % (script, docfile, output_file))
|
import sys
|
||||||
|
from subprocess import Popen, PIPE
|
||||||
|
|
||||||
|
options = sum([['--stringparam', key, value]
|
||||||
|
for key,value in options.items()], [])
|
||||||
|
|
||||||
|
proc = Popen(['xsltproc'] + options + [script, '-'],
|
||||||
|
stdin=PIPE, stdout=PIPE, stderr=PIPE)
|
||||||
|
|
||||||
|
result, stderr = proc.communicate(doc)
|
||||||
|
if stderr:
|
||||||
|
import planet
|
||||||
|
planet.logger.error(stderr)
|
||||||
|
|
||||||
if dom: dom.freeDoc()
|
if dom: dom.freeDoc()
|
||||||
if docfile: os.unlink(docfile)
|
|
||||||
|
return result
|
||||||
|
7
tests/data/filter/translate.ini
Normal file
7
tests/data/filter/translate.ini
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
[Planet]
|
||||||
|
filters = translate.xslt
|
||||||
|
filter_directories = tests/data/filter
|
||||||
|
|
||||||
|
[translate.xslt]
|
||||||
|
in = aeiou
|
||||||
|
out = AEIOU
|
20
tests/data/filter/translate.xslt
Normal file
20
tests/data/filter/translate.xslt
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
|
||||||
|
<xsl:param name="in"/>
|
||||||
|
<xsl:param name="out"/>
|
||||||
|
|
||||||
|
<!-- translate $in characters to $out in attribute values -->
|
||||||
|
<xsl:template match="@*">
|
||||||
|
<xsl:attribute name="{name()}">
|
||||||
|
<xsl:value-of select="translate(.,$in,$out)"/>
|
||||||
|
</xsl:attribute>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<!-- pass through everything else -->
|
||||||
|
<xsl:template match="node()">
|
||||||
|
<xsl:copy>
|
||||||
|
<xsl:apply-templates select="@*|node()"/>
|
||||||
|
</xsl:copy>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
</xsl:stylesheet>
|
||||||
|
|
25
tests/test_filter_xslt.py
Normal file
25
tests/test_filter_xslt.py
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import unittest, xml.dom.minidom
|
||||||
|
from planet import shell, config, logger
|
||||||
|
|
||||||
|
class XsltFilterTests(unittest.TestCase):
|
||||||
|
|
||||||
|
def test_xslt_filter(self):
|
||||||
|
config.load('tests/data/filter/translate.ini')
|
||||||
|
testfile = 'tests/data/filter/category-one.xml'
|
||||||
|
|
||||||
|
input = open(testfile).read()
|
||||||
|
output = shell.run(config.filters()[0], input, mode="filter")
|
||||||
|
dom = xml.dom.minidom.parseString(output)
|
||||||
|
catterm = dom.getElementsByTagName('category')[0].getAttribute('term')
|
||||||
|
self.assertEqual('OnE', catterm)
|
||||||
|
|
||||||
|
try:
|
||||||
|
import libxslt
|
||||||
|
except:
|
||||||
|
try:
|
||||||
|
from subprocess import Popen, PIPE
|
||||||
|
except ImportError:
|
||||||
|
logger.warn("libxslt is not available => can't test xslt filters")
|
||||||
|
del XsltFilterTests.test_xslt_filter
|
@ -92,6 +92,6 @@ try:
|
|||||||
del FilterTests.test_xpath_filter
|
del FilterTests.test_xpath_filter
|
||||||
|
|
||||||
except ImportError:
|
except ImportError:
|
||||||
logger.warn("Popen is not available => can't test filters")
|
logger.warn("Popen is not available => can't test standard filters")
|
||||||
for method in dir(FilterTests):
|
for method in dir(FilterTests):
|
||||||
if method.startswith('test_'): delattr(FilterTests,method)
|
if method.startswith('test_'): delattr(FilterTests,method)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user