"""xpath utilities""" #import copy #import os import sys from lxml import etree #xsimport docing from nitpo import Nitpo class Xpaths(Nitpo): def __init__(self, do_verbose=False): super().__init__() ns = self.const['ns'] self.N = {'n': self.const['ns']} self.nsmap = {None: ns} self.do_verbose = do_verbose def run(self, doc, xp): try: outs = doc.xpath(xp, namespaces=self.const['nsmap']) except etree.XPathEvalError: note = f"xpaths can't evalute '{xp}'" if self.is_dev(): raise Exception(note) print(note, file=sys.stderr) return None return outs def has_it(self, doc, xp): count = len(doc.xpath(xp, namespaces=self.const['nsmap'])) if count == 0: return False return True def txt(self, doc): string = etree.tostring(doc, pretty_print=True).decode() return string def zero_or_one(self, doc, xp): outs = self.run(doc, xp) if outs is None: return [] if outs is False: return [] if outs is True: return [] if len(outs) == 0: return [] if len(outs) == 1: return outs[0] err = self.txt(doc) + ' must not have several ' + xp if self.is_dev(): raise Exception(err) print(err, file=sys.stderr) return outs[0] def all(self, doc, xp): outs = self.run(doc, xp) return outs def none_or_one(self, doc, xp): outs = self.run(doc, xp) if len(outs) == 0: return None if len(outs) == 1: return outs[0] err = self.txt(doc) + ' must not have several ' + xp if self.is_dev(): raise Exception(err) print(err, file=sys.stderr) return outs[0] def one_or_last(self, doc, xp): outs = self.run(doc, xp) if len(outs) == 0: err = self.txt(doc) + ' must have at least one ' + xp if self.is_dev(): raise Exception(err) return None return outs[-1] def one_or_first(self, doc, xp): outs = self.run(doc, xp) if len(outs) == 0: err = self.txt(doc) + ' must have at least one ' + xp if self.is_dev(): raise Exception(err) return None return outs[0] def one(self, doc, xp): outs = self.run(doc, xp) if len(outs) == 0: err = self.txt(doc) + ' must have ' + xp if self.is_dev(): raise Exception(err) print(err, file=sys.stderr) if len(outs) == 1: return outs[0] err = self.txt(doc) + ' must not have several ' + xp if self.is_dev(): raise Exception(err) print(err, file=sys.stderr) return outs[0]