import SCons.Util import xml.dom.minidom, os, os.path ################################################################################ # XSLT processor ################################################################################ def generate(env) : def generate_actions(source, target, env, for_signature) : if not env.has_key("XSLTSTYLESHEET") : raise SCons.Errors.UserError("The XSLTSTYLESHEET construction variable must be defined") # Process the XML catalog files # FIXME: It's probably not clean to do an ENV assignment globally env["ENV"]["XML_CATALOG_FILES"] = " ".join(env.get("XMLCATALOGS", "")) # Build the XMLLint command xmllintcmd = ["$XMLLINT", "--nonet", "--xinclude", "--postvalid", "--noout", "$SOURCE"] # Build the XSLT command xsltcmd = ["$XSLT", "--nonet", "--xinclude"] for (param, value) in env["XSLTPARAMS"] : xsltcmd += ["--stringparam", param, value] xsltcmd += ["-o", "$TARGET", "$XSLTSTYLESHEET", "$SOURCE"] return [ SCons.Action.Action([xmllintcmd], cmdstr = "$XMLLINTCOMSTR"), SCons.Action.Action([xsltcmd], cmdstr = "$XSLTCOMSTR")] def modify_sources(target, source, env) : if len(env["FOCFG"]) > 0 : source.append(env["FOCFG"]) source.append(env.get("XMLCATALOGS", [])) return target, source def scan_xml(node, env, path) : dependencies = set() nodes = [node] while len(nodes) > 0 : node = nodes.pop() try : document = xml.dom.minidom.parseString(node.get_contents()) except xml.parsers.expat.ExpatError: continue for include in document.getElementsByTagNameNS("http://www.w3.org/2001/XInclude", "include") : include_file = include.getAttribute("href") dependencies.add(include_file) if include.getAttribute("parse") != "text" : nodes.append(env.File(include_file)) return list(dependencies) env["XMLLINT"] = "xmllint" env["XSLT"] = "xsltproc" env["XSLTPARAMS"] = [] env["BUILDERS"]["XSLT"] = SCons.Builder.Builder( generator = generate_actions, emitter = modify_sources, source_scanner = SCons.Scanner.Scanner(function = scan_xml), src_suffix = ".xml" ) def exists(env) : return True