0001
0002
0003"""Kid tranformations"""
0004
0005__revision__ = "$Rev: 492 $"
0006__date__ = "$Date: 2007-07-06 21:38:45 -0400 (Fri, 06 Jul 2007) $"
0007__author__ = "Ryan Tomayko (rtomayko@gmail.com)"
0008__copyright__ = "Copyright 2004-2005, Ryan Tomayko"
0009__license__ = "MIT <http://www.opensource.org/licenses/mit-license.php>"
0010
0011from kid.parser import ElementStream, START, XML_DECL, document, _coalesce
0012from kid.namespace import Namespace
0013from kid.template_util import generate_content
0014
0015__all__ = ['transform_filter']
0016
0017
0018def transform_filter(stream, template):
0019 templates = template._get_match_templates()
0020 def apply_func(item):
0021 return transform_filter(generate_content(item), template)
0022 stream = ElementStream.ensure(stream)
0023 return ElementStream(apply_matches(stream, template, templates, apply_func))
0024
0025def apply_matches(stream, template, templates, apply_func):
0026 for ev, item in stream:
0027 if ev == START:
0028 matched = False
0029 for i in range(0, len(templates)):
0030 match, call = templates[i]
0031 if match(item):
0032 item = stream.expand()
0033 newstream = _coalesce(call(template, item, apply_func),
0034 template._get_assume_encoding())
0035 if len(templates) < 2:
0036 for ev, item in newstream:
0037 yield ev, item
0038 else:
0039 for ev, item in apply_matches(
0040 ElementStream(newstream), template,
0041 templates[:i] + templates[i+1:], apply_func):
0042 yield ev, item
0043 matched = True
0044 break
0045 if matched:
0046 continue
0047 yield ev, item
0048
0049
0050def xinclude_filter(stream, template):
0051 xi = Namespace('http://www.w3.org/2001/XInclude')
0052 include = xi.include
0053 fallback = xi.fallback
0054 for ev, item in stream:
0055 if ev == START and item.tag == include:
0056 item = item.expand()
0057 href = item.get('href')
0058 try:
0059 doc = document(href, template._get_assume_encoding())
0060 except:
0061 fallback_elm = item.find(fallback)
0062 for ev, item in ElementStream(fallback_elm).strip(1):
0063 yield ev, item
0064 else:
0065 for ev, item in doc:
0066 if ev != XML_DECL:
0067 yield ev