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()
|
||||
|
||||
planet_predefined_options = []
|
||||
planet_predefined_options = ['filters']
|
||||
|
||||
def __init__():
|
||||
"""define the struture of an ini file"""
|
||||
|
@ -1,5 +1,19 @@
|
||||
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={}):
|
||||
""" process an XSLT stylesheet """
|
||||
|
||||
@ -12,6 +26,22 @@ def run(script, doc, output_file=None, options={}):
|
||||
except:
|
||||
# otherwise, use the command line interface
|
||||
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
|
||||
if hasattr(warnings, 'simplefilter'):
|
||||
warnings.simplefilter('ignore', RuntimeWarning)
|
||||
@ -20,16 +50,28 @@ def run(script, doc, output_file=None, options={}):
|
||||
file.write(doc)
|
||||
file.close()
|
||||
|
||||
# do it
|
||||
if dom:
|
||||
styledoc = libxml2.parseFile(script)
|
||||
style = libxslt.parseStylesheetDoc(styledoc)
|
||||
result = style.applyStylesheet(dom, None)
|
||||
style.saveResultToFilename(output_file, result, 0)
|
||||
style.freeStylesheet()
|
||||
result.freeDoc()
|
||||
cmdopts = []
|
||||
for key,value in options.items():
|
||||
cmdopts += ['--stringparam', key, quote(value, apos=r"\'")]
|
||||
|
||||
os.system('xsltproc %s %s %s > %s' %
|
||||
(script, ' '.join(cmdopts), docfile, output_file))
|
||||
os.unlink(docfile)
|
||||
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 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
|
||||
|
||||
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):
|
||||
if method.startswith('test_'): delattr(FilterTests,method)
|
||||
|
Loading…
x
Reference in New Issue
Block a user