def processXSL(self, onebox, name, results): """ does the following steps with the XSL in the resultsTemplate element: <ol> <li> write each resultsTemplate to its own file, with the name of the onebox module. If there was a file of that name there, it's overwritten. </li> <li> rewrite the customer-onebox.xsl file to call each module's stylesheet with the appropriate match statement </li> </ol> Returns: err string if an error occurs, True if this onebox has a resultsTemplate and it was written to a file, and None if both those were not true. """ print "processXSL called for %s" % name # parse this XML stylesheet = results[0].childNodes if not stylesheet: print "no results 2" return None newdoc = xml.dom.minidom.Document() stylesheetNode = newdoc.createElement("xsl:stylesheet") stylesheetNode.setAttribute("xmlns:xsl", 'http://www.w3.org/1999/XSL/Transform') stylesheetNode.setAttribute("version", "1.0") newdoc.appendChild(stylesheetNode) for node in stylesheet: if node.nodeType != xml.dom.Node.TEXT_NODE: stylesheetNode.appendChild(node) if not stylesheetNode.firstChild: # if no nodes in there return None xsl = newdoc.toxml(encoding="utf-8") try: xslDom = xml.dom.minidom.parseString(xsl) # this comes from a C extension to Python, and can't be named any better: except Exception: e = sys.exc_info()[1] logging.exception("error in %s at line %d" % (name,e.getLineNumber())) logging.info("xml with error is: " + xsl) return "error in " + name temps = xslDom.getElementsByTagName('xsl:template') # NOTE namespace if not temps: return('no xsl:template element found in ' + name) temps[0].setAttribute('name', name) f = open("%s/%s.xsl" % (self.xslDir, name), "w") print "writing this xsl to " + name f.write(xslDom.toxml(encoding="utf-8")) f.close() return "0"
def parseXML(self, configBody): try: dom = xml.dom.minidom.parseString(configBody) # this comes from a C extension to Python, and can't be named any better: except Exception: logging.exception("parse error in XML") return "parse error in XML" oneboxes = dom.getElementsByTagName('onebox') if not oneboxes: logging.info('No onebox modules found') return None # find the stylesheet dir: self.xslDir = self.cfg.getGlobalParam('ENTFRONT_STYLESHEETS_DIR') if not self.xslDir: logging.error("failed to find stylesheet dir") return "failed to find stylesheet dir" xslNames = [] # list of the oneboxes with their own XSL # create for onebox in oneboxes: nameNodes = onebox.getElementsByTagName('name') if not nameNodes: return "failed to find name element" elif len(nameNodes) > 1: return "more than one name element" name = getText(nameNodes[0].childNodes) results = onebox.getElementsByTagName('resultsTemplate') if len(results) > 1: return "more than one 'resultsTemplate' node found in " + name elif results: err = self.processXSL(onebox, name, results) if err: if err[0] != '0': return err else: xslNames.append(name) # Remove resultsTemplate element from config because backend # doesn't understand it. onebox.removeChild(results[0]) # write out a config file without resultsTemplate for the # backend backendFileName = self.cfg.getGlobalParam("ONEBOX_BACKEND_CONFIG") if backendFileName == None: logging.info("failed to find config file") return "1\n%s" % "failed to find config file" logging.info("backend config file is %s" % backendFileName) backendFile = open(backendFileName, "w") if not backendFile: logging.info("can't open " + backendFileName) return "1\n" backendFile.write(dom.toxml(encoding="utf-8")); backendFile.close() # rewrite the master XSL that calls each individual one: custFile = open(self.xslDir + os.sep + custFileName, "w") custFile.write(customerHeader) for name in xslNames: custFile.write(customerImport % name) custFile.write('\n') # in XSL, the imports need to precede the includes: custFile.write(includeDefault) custFile.write(invokeDefault) for name in xslNames: custFile.write(customerInvocation %(name, name, name)) custFile.write(customerTrailer) custFile.close() # touch each frontend stylesheet that includes any oneboxes, # so the file watcher will notice: for frontend in dom.getElementsByTagName("Frontend"): if frontend.attributes: name = frontend.attributes["name"] if name: ssName = self.xslDir + os.sep + name.nodeValue if os.path.exists(ssName): os.system("touch " + ssName)