""" Jaide standalone utility functions. """ from os import path from lxml import etree, objectify import xml.etree.ElementTree as ET def clean_lines(commands): """ Generate strings that are not comments or lines with only whitespace. Purpose: This function is a generator that will read in either a | plain text file of strings(IP list, command list, etc), a | comma separated string of strings, or a list of strings. It | will crop out any comments or blank lines, and yield | individual strings. | | Only strings that do not start with a comment '#', or are not | entirely whitespace will be yielded. This allows a file with | comments and blank lines for formatting neatness to be used | without a problem. @param commands: This can be either a string that is a file | location, a comma separated string of strings | ('x,y,z,1,2,3'), or a python list of strings. @type commands: str or list @returns: Yields each command in order @rtype: iterable of str """ if isinstance(commands, basestring): # if the command argument is a filename, we need to open it. if path.isfile(commands): commands = open(commands, 'rb') # if the command string is a comma separated list, break it up. elif len(commands.split(',')) > 1: commands = commands.split(',') else: # if a single command, need to just be returned. try: if commands.strip()[0] != "#": yield commands.strip() + '\n' return except IndexError: pass elif isinstance(commands, list): pass else: raise TypeError('clean_lines() accepts a \'str\' or \'list\'') for cmd in commands: # exclude commented lines, and skip blank lines (index error) try: if cmd.strip()[0] != "#": yield cmd.strip() + '\n' except IndexError: pass def xpath(source_xml, xpath_expr, req_format='string'): """ Filter xml based on an xpath expression. Purpose: This function applies an Xpath expression to the XML | supplied by source_xml. Returns a string subtree or | subtrees that match the Xpath expression. It can also return | an xml object if desired. @param source_xml: Plain text XML that will be filtered @type source_xml: str or lxml.etree.ElementTree.Element object @param xpath_expr: Xpath expression that we will filter the XML by. @type xpath_expr: str @param req_format: the desired format of the response, accepts string or | xml. @type req_format: str @returns: The filtered XML if filtering was successful. Otherwise, | an empty string. @rtype: str or ElementTree """ tree = source_xml if not isinstance(source_xml, ET.Element): tree = objectify.fromstring(source_xml) # clean up the namespace in the tags, as namespaces appear to confuse # xpath method for elem in tree.getiterator(): # beware of factory functions such as Comment if isinstance(elem.tag, basestring): i = elem.tag.find('}') if i >= 0: elem.tag = elem.tag[i+1:] # remove unused namespaces objectify.deannotate(tree, cleanup_namespaces=True) filtered_list = tree.xpath(xpath_expr) # Return string from the list of Elements or pure xml if req_format == 'xml': return filtered_list matches = ''.join(etree.tostring( element, pretty_print=True) for element in filtered_list) return matches if matches else ""