def nodeParents(dom, node): parents = [] parent = xpath.findnode('..', node) while parent and not isinstance(parent, minidom.Document): parents.append(parent) parent = xpath.findnode('..', parent) return parents
def getLabelText(self, label): l = xpath.findnode('label', label) text = None if label.attributes.get('id'): # Try getting programatically set label first. text = xbmc.getInfoLabel('Control.GetLabel({0})'.format( label.attributes.get('id').value)) if not text or text == '-': text = None if l and l.childNodes: text = l.childNodes[0].data if text: if text.isdigit(): text = '$LOCALIZE[{0}]'.format(text) else: i = xpath.findnode('info', label) if i and i.childNodes: text = i.childNodes[0].data if text.isdigit(): text = '$LOCALIZE[{0}]'.format(text) else: text = '$INFO[{0}]'.format(text) if not text: return None return tagRE.sub('', text).replace('[CR]', '... ').strip(' .')
def waitValue(self, location): with self: node = xpath.findnode(location, self._doc.documentElement) if not node: self.waitLocation(location) node = xpath.findnode(location, self._doc.documentElement) assert node return self.getXPathForElement(node)
def pullValue(self, location): """Wait for a value, remove it from the document, return it (as string)""" with self: node = xpath.findnode(location, self._doc.documentElement) if not node: self.waitLocation(location) node = xpath.findnode(location, self._doc.documentElement) assert node rv = xpath.expr.string_value(node) node.parentNode.removeChild(node) self.signalNodelist(nodeSet(parentnode)) return rv
def getVariable(self, name): var = xpath.findnode(".//variable[attribute::name='{0}']".format(name), xpath.findnode('includes', self.xml)) if not var: return '' for val in xpath.find('.//value', var): conditionAttr = val.attributes.get('condition') if not conditionAttr: return val.childNodes[0].data or '' else: if xbmc.getCondVisibility(conditionAttr.value): # print condition # print repr(val.string) return val.childNodes[0].data or '' return ''
def processIncludes(self): self.includes = Includes() for i in xpath.find('//include', self.xml): conditionAttr = i.attributes.get('condition') if conditionAttr and not xbmc.getCondVisibility( conditionAttr.value): xpath.findnode('..', i).removeChild(i) continue matchingInclude = self.includes.getInclude(i.childNodes[0].data) if not matchingInclude: # print 'INCLUDE NOT FOUND: %s' % i.string continue # print 'INCLUDE FOUND: %s' % i.string new = matchingInclude.cloneNode(True) xpath.findnode('..', i).replaceChild(new, i)
def trackValue(self, location, generation): """Generator. Like waitValue, but keeps on returning changed paths""" with self: generation = self.waitLocation(location, generation) node = xpath.findnode(location, self._doc.documentElement) assert node return self.getXPathForElement(node), generation
def newValue(self, location, where, name, value): """Insert a single new node into the document (value passed as a string)""" with self: # Create the new node to be instered newnode = self._doc._createElementWithEscaping(name) if not isinstance(value, basestring): value = str(value) newnode.appendChild(self._doc.createTextNode(value)) # Find the node that we want to insert it relative to node = xpath.findnode(location, self._doc.documentElement) if node is None: raise DBKeyError(location) # Insert it in the right place if where == 'before': node.parentNode.insertBefore(node, newnode) elif where == 'after': newnode.nextSibling = node.nextSibling node.nextSibling = newnode elif where == 'child': node.appendChild(newnode) else: raise DBParamError('where must be before, after or child') # Signal anyone waiting self.signalNodelist( recursiveNodeSet(newnode) + nodeSet(newnode.parentNode)) # Return the location of the new node return self.getXPathForElement(newnode)
def hasValue(self, location): """Return xpath if the location exists, None otherwise""" with self: node = xpath.findnode(location, self._doc.documentElement) if node: return self.getXPathForElement(node) return None
def test_root(self): doc = xml.dom.minidom.parseString(""" <doc><a><b><context /></b></a></doc> """).documentElement node = xpath.findnode('//context', doc) result = xpath.find('/', node) self.failUnlessEqual([x.nodeType for x in result], [xml.dom.Node.DOCUMENT_NODE])
def replace(from_doc, from_path, to_doc, to_path): '''replace one node in the destination doc with one or more nodes from the source doc''' to_node = xpath.findnode(to_path, to_doc) if to_node: parent = to_node.parentNode from_nodes = xpath.find(from_path, from_doc) for x in from_nodes: parent.insertBefore(x, to_node) parent.removeChild(to_node)
def test_self(self): doc = xml.dom.minidom.parseString(""" <doc> <para /> </doc> """).documentElement para_node = xpath.findnode('para', doc) self.failUnlessEqual(len(xpath.find('self::para', doc)), 0) self.failUnlessEqual(len(xpath.find('self::para', para_node)), 1)
def append(from_doc, from_path, to_doc, to_path): '''append one or more nodes from the source doc to a node in the destination doc''' to_node = xpath.findnode(to_path, to_doc) if to_node: from_nodes = xpath.find(from_path, from_doc) for x in from_nodes: if x.nodeType == Node.ATTRIBUTE_NODE: to_node.setAttribute(x.name, x.value) else: to_node.appendChild(x)
def test_root_descendant(self): doc = xml.dom.minidom.parseString(""" <doc> <para id="1"><context /></para> <para id="2" /> </doc> """).documentElement node = xpath.findnode('//context', doc) result = xpath.find('/descendant::para', node) self.failUnlessEqual([x.getAttribute("id") for x in result], ["1", "2"])
def delValue(self, location): """Remove a single node from the document""" with self: node = xpath.findnode(location, self._doc.documentElement) if node is None: raise DBKeyError(location) parentNode = node.parentNode parentNode.removeChild(node) # Signal anyone waiting self.signalNodelist(nodeSet(parentNode))
def test_previous_sibling(self): doc = xml.dom.minidom.parseString(""" <doc> <chapter id="1" /><chapter id="2" /> <context /> <chapter id="3" /><chapter id="4" /> </doc> """).documentElement node = xpath.findnode('//context', doc) result = xpath.find('preceding-sibling::chapter[position()=1]', node) self.failUnlessEqual([x.getAttribute("id") for x in result], ["2"])
def test_next_sibling(self): doc = xml.dom.minidom.parseString(""" <doc> <chapter id="1" /><chapter id="2" /> <context /> <chapter id="3" /><chapter id="4" /> </doc> """).documentElement node = xpath.findnode('//context', doc) result = xpath.find('following-sibling::chapter[position()=1]', node) self.assertEqual([x.getAttribute("id") for x in result], ["3"])
def test_parent_attr(self): doc = xml.dom.minidom.parseString(""" <doc id="0"> <chapter id="1" lang="en"> <item id="2" /> <item id="3"><subitem id="4" /></item> </chapter> </doc> """).documentElement node = xpath.findnode('//item[@id="3"]', doc) result = xpath.find('../@lang', node) self.failUnlessEqual([x.value for x in result], ["en"])
def test_parent(self): doc = xml.dom.minidom.parseString(""" <doc id="0"> <chapter id="1"> <item id="2" /> <item id="3"><subitem id="4" /></item> </chapter> </doc> """).documentElement node = xpath.findnode('//item[@id="3"]', doc) result = xpath.find('..', node) self.failUnlessEqual([x.getAttribute("id") for x in result], ["1"])
def test_relative_descendant_or_self(self): doc = xml.dom.minidom.parseString(""" <para id="0"> <div id="1" /> <para id="2"> <para id="3" /> </para> </para> """).documentElement node = xpath.findnode('//para[@id="2"]', doc) result = xpath.find('.//para', node) self.failUnlessEqual([x.getAttribute("id") for x in result], ["3"])
def prepend(from_doc, from_path, to_doc, to_path): '''append one or more nodes from the source doc to a node in the destination doc''' to_node = xpath.findnode(to_path, to_doc) if to_node: from_nodes = xpath.find(from_path, from_doc) first = to_node.firstChild if first: for x in from_nodes: to_node.insertBefore(x, first) else: for x in from_nodes: to_node.appendChild(x)
def test_olist_item(self): doc = xml.dom.minidom.parseString(""" <doc> <item id="1"> <context /> <olist><item id="2" /></olist> </item> <olist><item id="3" /></olist> </doc> """).documentElement node = xpath.findnode('//context', doc) result = xpath.find('/descendant::olist/child::item', node) self.failUnlessEqual([x.getAttribute("id") for x in result], ["2", "3"])
def test_ancestor_or_self(self): doc = xml.dom.minidom.parseString(""" <doc> <div id="1"> <div id="2" /> <div id="3" /> </div> <div id="4" /> </doc> """).documentElement node = xpath.findnode('//div[@id="3"]', doc) result = xpath.find('ancestor-or-self::div', node) self.failUnlessEqual([x.getAttribute("id") for x in result], ["1", "3"])
def controlIsVisible(self, control): visible = xpath.findnode('visible', control) if not visible: return True if not visible.childNodes: return True condition = visible.childNodes[0].data if self.currentControl: condition = condition.replace( 'ListItem.Property', 'Container({0}).ListItem.Property'.format(self.currentControl)) if not xbmc.getCondVisibility(condition): return False else: return True
def loadIncludesFiles(self): if self._includesFilesLoaded: return basePath = getXBMCSkinPath('') for i in xpath.find('//include', xpath.findnode('//includes', self.xml)): fileAttr = i.attributes.get('file') if fileAttr: xmlName = xbmc.validatePath(fileAttr.value) p = os.path.join(basePath, xmlName) if not os.path.exists(p): continue xml = minidom.parse(p) includes = xpath.findnode('includes', xml) xpath.findnode('..', i).replaceChild(includes, i) for sub_i in xpath.find('.//include', includes): nameAttr = sub_i.attributes.get('name') if nameAttr: self.includesMap[nameAttr.value] = sub_i else: nameAttr = i.attributes.get('name') if nameAttr: self.includesMap[nameAttr.value] = i.cloneNode(True) self._includesFilesLoaded = True
def test_partition(self): """Test that the ancestor, descendant, following, preceding, and self axes partition the document. """ a = xpath.find('//*', self.doc) a.sort() b = [] node = xpath.findnode('//*[@id="2.2"]', self.doc) for axis in ('ancestor','descendant','following','preceding','self'): b.extend(xpath.find('%s::*' % axis, node)) b.sort() self.failUnlessEqual(a, b)
def test_ancestors(self): doc = xml.dom.minidom.parseString(""" <doc> <div id="1"> <div id="2"> <context /> </div> <div id="3" /> </div> <div id="4" /> </doc> """).documentElement node = xpath.findnode('//context', doc) result = xpath.find('ancestor::div', node) self.assertEqual([x.getAttribute("id") for x in result], ["1", "2"])
def test_partition(self): """Test that the ancestor, descendant, following, preceding, and self axes partition the document. """ a = xpath.find('//*', self.doc) a.sort(key=id) b = [] node = xpath.findnode('//*[@id="2.2"]', self.doc) for axis in ('ancestor', 'descendant', 'following', 'preceding', 'self'): b.extend(xpath.find('%s::*' % axis, node)) b.sort(key=id) self.assertEqual(a, b)
def getListItemTexts(self, controlID): self.currentControl = controlID try: clist = self.getControl(controlID) if not clist: return None fl = xpath.findnode("focusedlayout", clist) if not fl: return None lt = xpath.find( "//control[attribute::type='label' or attribute::type='fadelabel' or attribute::type='textbox']", fl) texts = [] for l in lt: if not self.controlIsVisibleGlobally(l): continue text = self.getLabelText(l) if text and text not in texts: texts.append(text) return self.processTextList(texts) finally: self.currentControl = None
def setValue(self, location, value): """Set (or insert) a single node by a given value (passed as a string)""" with self: # Find the node, if it exists. node = xpath.findnode(location, self._doc.documentElement) if node is None: # Does not exist yet. Try to add it. parent, child = self.splitXPath(location) if not parent or not child: raise DBKeyError( "XPath %s does not refer to unique new or existing location" % location) return self.newValue(parent, 'child', child, value) # Sanity check if node.nodeType == node.DOCUMENT_NODE: raise DBParamError('Cannot replace value of /') # Clear out old contents of the node while node.firstChild: node.removeChild(node.firstChild) if hasattr(value, 'nodeType'): # It seems to be a DOM node. Insert it. node.appendChild(value) else: # Insert the new text value if not isinstance(value, basestring): value = str(value) node.appendChild(self._doc.createTextNode(value)) # Signal anyone waiting self.signalNodelist(recursiveNodeSet(node)) # Return the location of the new node return self.getXPathForElement(node)
def get_tgs_codecover_raw(tar): ## overview / filenames information f = tar.extractfile('coverage/report.csv') reader = csv.reader(f) packages = set([]) name_to_full_name_map = {} ## short name -> array of full names for row in reader: if row[2] == 'package': packages.add(row[0]) if row[2] == 'class' and '.'.join(row[0].split('.')[:-1]) in packages: name = row[0].split('.')[-1] if name in name_to_full_name_map: l = name_to_full_name_map[name] else: l = [] l.append(row[0].replace('.', '/') + '.java') name_to_full_name_map[name] = l ## code coverage information f = tar.extractfile('coverage/report_html/report_single.html') tree = parse(f) ## next, read hyperlinking information from the overview table! tbody = xpath.find('//tbody[@class="overview"]', tree)[0] trs = [elem for elem in tbody.getElementsByTagName("tr")] first_tds = [tr.getElementsByTagName("td")[0] for tr in trs] first_tds_names = reduce( lambda a, b: a + b, [[(a.getAttribute("href"), a.firstChild.nodeValue.strip()) for a in td.getElementsByTagName("a")] for td in first_tds]) filtered_tds_names = [(x, y) for (x, y) in first_tds_names if y in name_to_full_name_map] xrefs = [ xpath.findnode('//a[@name="%s"]' % name[1:], tree) for (name, _) in filtered_tds_names ] code_hash = [myx.parentNode.parentNode.getAttribute('id') for myx in xrefs] regexp_match = [re.match('F(\d+)(L\d+)?', x) for x in code_hash] regexp_numbers = [ int(match.group(1)) if match else 0 for match in regexp_match ] zipped_numbers = zip(regexp_numbers, map(lambda (_, x): x, filtered_tds_names)) def relevant_numbers(fn): return [x for (x, y) in zipped_numbers if y == fn] #print name_to_full_name_map #print filtered_tds_names #print regexp_numbers #print zipped_numbers ## next build up this map fmap = { name: zip(name_to_full_name_map[name], relevant_numbers(name)) for name in name_to_full_name_map } #print fmap ## and the short fname map short_name_elems = [ s.replace('.java', '') for s in xpath.findvalues('//thead[@class="code"]/tr/th/text()', tree) ] #print short_name_elems ## lines = xpath.find('//tbody[@class="code"]/tr[@class="code"]/td[@class="code text"]', tree) ## parse lines def get_lines(): tbodys = xpath.find('//tbody[@class="code"]', tree) trs = reduce(lambda a, b: a + b, [[ elem for elem in tbody.getElementsByTagName("tr") if elem.getAttribute('class') == 'code' ] for tbody in tbodys]) tds = reduce(lambda a, b: a + b, [[ elem for elem in tr.getElementsByTagName("td") if elem.getAttribute('class') == 'code text' ] for tr in trs]) return tds lines = get_lines() result = [] for line in lines: lnumberStr = line.parentNode.getAttribute('id') if not lnumberStr.startswith('F'): lnumberStr = 'F0' + lnumberStr fnumber, lnumber = map(int, re.match(r'F(\d+)L(\d+)', lnumberStr).groups()) text = [] def get_text_nodes(n): if n.nodeType == line.TEXT_NODE: text.append(n.nodeValue) for child in n.childNodes: get_text_nodes(child) get_text_nodes(line) code = ''.join(text).strip() is_unreachable_in_bytecode = code in ["continue;", "break;"] fully_cvrd, partially_cvrd, not_cvrd = [ len(xpath.find('span[contains(@class, "%s")]' % token, line)) > 0 for token in ("fullyCovered", "partlyCovered", "notCovered") ] terms_only = all( len( xpath.find('span[contains(@class, "%s_Coverage")]' % token, line)) == 0 for token in ("Loop", "Branch", "Statement", "Operator")) branches_only = all( ## Terms are allowed too, e.g., } else if { ... len( xpath.find('span[contains(@class, "%s_Coverage")]' % token, line)) == 0 for token in ("Loop", "Statement", "Operator")) ## ok now, this is ugly:::: this_line_short_fname = short_name_elems[fnumber] #print fmap[this_line_short_fname], fnumber ## search in the fmap for the last item that has idx <= this fnumber!!!! this_line_full_name = [ full for (full, idx) in fmap[this_line_short_fname] if idx <= fnumber ][-1] result.append( ((this_line_full_name, lnumber), fully_cvrd, partially_cvrd, not_cvrd, terms_only, branches_only, is_unreachable_in_bytecode)) return result
def find_node_by_xpath(node, pattern): return xpath.findnode(pattern,node)
def getControl(self, controlID): return xpath.findnode( "//control[attribute::id='{0}']".format(controlID), self.xml)
def _find(root, xpath_expr): return xpath.findnode(xpath_expr, root)
def parse(self, node): return xpath.findnode(self.selector, node)