def _buildMetadata(self, xpath, metadata = {}):
        parentXpath = xpath[:xpath.rfind("/")]
        childXpath = xpath[xpath.rfind("/") + 1:]

        if len(parentXpath) > 0:
            try:
                metadata[parentXpath].append(childXpath)
            except:
                metadata[parentXpath] = [childXpath]

        attributes = None
        next = iter(ElementPath.xpath_tokenizer(childXpath)).next

        while 1:
                try:
                    token = next()
                    if token[0] == "[":
                        attributes = self._transformAttr(next, token)
                except StopIteration:
                    break

        if attributes is not None:
            childXpath = xpath[:xpath.rfind("[")]

        return childXpath, attributes
Exemplo n.º 2
0
 def iterfind(self, path, namespaces=None):
     # compile selector pattern
     if path[-1:] == "/":
         path = path + "*"  # implicit all (FIXME: keep this?)
     try:
         selector = ElementPath._cache[path]
     except KeyError:
         if len(ElementPath._cache) > 100:
             ElementPath._cache.clear()
         if path[:1] == "/":
             raise SyntaxError("cannot use absolute path on element")
         it = iter(ElementPath.xpath_tokenizer(path, namespaces))
         next_ = lambda: next(it)
         token = next_()
         selector = []
         while 1:
             try:
                 selector.append(ElementPath.ops[token[0]](next_,
                                                           token))
             except StopIteration:
                 raise SyntaxError("invalid path")
             try:
                 token = next_()
                 if token[0] == "/":
                     token = next_()
             except StopIteration:
                 break
         ElementPath._cache[path] = selector
     # execute selector pattern
     result = [self]
     context = self._SelectorContext(self)
     for select in selector:
         result = select(context, result)
     return result
Exemplo n.º 3
0
 def iterfind(self, path, namespaces=None):
     # compile selector pattern
     if path[-1:] == "/":
         path = path + "*" # implicit all (FIXME: keep this?)
     try:
         selector = ElementPath._cache[path]
     except KeyError:
         if len(ElementPath._cache) > 100:
             ElementPath._cache.clear()
         if path[:1] == "/":
             raise SyntaxError("cannot use absolute path on element")
         it = iter(ElementPath.xpath_tokenizer(path, namespaces))
         next_ = lambda: next(it)
         token = next_()
         selector = []
         while 1:
             try:
                 selector.append(ElementPath.ops[token[0]](next_, token))
             except StopIteration:
                 raise SyntaxError("invalid path")
             try:
                 token = next_()
                 if token[0] == "/":
                     token = next_()
             except StopIteration:
                 break
         ElementPath._cache[path] = selector
     # execute selector pattern
     result = [self]
     context = self._SelectorContext(self)
     for select in selector:
         result = select(context, result)
     return result
Exemplo n.º 4
0
    def _buildMetadata(self, xpath, metadata={}):
        parentXpath = xpath[:xpath.rfind("/")]
        childXpath = xpath[xpath.rfind("/") + 1:]

        if len(parentXpath) > 0:
            try:
                metadata[parentXpath].append(childXpath)
            except:
                metadata[parentXpath] = [childXpath]

        attributes = None
        next = iter(ElementPath.xpath_tokenizer(childXpath)).next

        while 1:
            try:
                token = next()
                if token[0] == "[":
                    attributes = self._transformAttr(next, token)
            except StopIteration:
                break

        if attributes is not None:
            childXpath = xpath[:xpath.rfind("[")]

        return childXpath, attributes
Exemplo n.º 5
0
    def test_predicate(self):
        """Test predicate addition
        """
        element_test = ET.Element("test")
        element_temp = ET.Element("test")
        element_temp.text = "Hey"
        element_temp.set("val", "8")
        ET.SubElement(element_temp, "ins")

        token_iter = EP.xpath_tokenizer("@val=8]")
        xmlconfigparse.add_predicate(token_iter, element_test)
        token_iter = EP.xpath_tokenizer("text()=Hey]")
        xmlconfigparse.add_predicate(token_iter, element_test)
        token_iter = EP.xpath_tokenizer("ins/]")
        xmlconfigparse.add_predicate(token_iter, element_test)

        element_temp_string = ET.tostring(element_temp)
        element_test_string = ET.tostring(element_test)
        self.assertEqual(
            element_test_string, element_temp_string, msg="Unexpected string returned"
        )
Exemplo n.º 6
0
    def test_elementinset(self):
        """Test method insert subelements
        """
        element_test = ET.Element("test")
        element_temp = ET.Element("test")
        new_temp = ET.SubElement(element_temp, "new")
        ET.SubElement(new_temp, "insert")
        token_iter = EP.xpath_tokenizer("new/insert")
        xmlconfigparse.elementinsert(token_iter, element_test)

        element_temp_string = ET.tostring(element_temp)
        element_test_string = ET.tostring(element_test)
        self.assertEqual(
            element_test_string, element_temp_string, msg="Unexpected string returned"
        )
Exemplo n.º 7
0
def xmlinsert(xpath, xmlfile, tag=".", findall=False):
    """Inserts elements from an xpath

    refs: xml.etree.ElementPath
          https://github.com/python/cpython/blob/3.7/Lib/xml/etree/ElementPath.py

    Args:
        xpath (str): xml elements separated by back slash
            (no whitespace outside of attributes)
        xmlfile (str): path to xml file; created if it doesn't exist
        tag (str): xml element to serve as parent (/ or . = root)
        findall (bool): If true finds all matching times matching tag
            and inserts xml elements from xpaths after deepest member
    Returns:
        str: location of updated xml file

    Notes:
        xpath (str): expects paths which only descend.  And supports
            the following symbols in xpath /()[]@= excludes (//, ..)
            ex. a[bar=/hello/world]/be[text()="there"]/can[@nope=there]/day

        tag (str): used by implementation of Elementree's iterfind function
            so see xml.etree.elementree for limitations.
    """
    # import xml and convert to element
    tree = ET.parse(xmlfile)
    root = tree.getroot()
    # no absolute paths
    if xpath[0] == "/":
        raise SyntaxError("Can't create another root directory in an xml file")
    token_iter = EP.xpath_tokenizer(xpath)
    # check recursive
    if findall:
        for element in root.iterfind(tag):
            elementinsert(token_iter, element)
    else:
        # if tag defined root replaced
        elementinsert(token_iter, root.find(tag))
    tree.write(xmlfile)
    return xmlfile
    def ExportXML(self, filename = None):
        """ Build element tree from xpaths """

        # Tree root node
        root = None

        #Map to store xpath and ElementXpath
        self.mapparentelem = {}

        ''' Select all rows of db to export '''
        for xpath in self.Iterators('/'):
            #Is attribute xpath? /a/b/c@name => attr name
            attr_xpath = False 

            try:
              value = str(self.Read(xpath))
            except SystemError, e:
              print "Cannot read [%s], error %s" % (xpath,str(e))
              continue
            next = iter(ElementPath.xpath_tokenizer(xpath)).next

            #For each leaf node on xpath
            current_elemment = root

            #parent xpath
            parent_xpath = None

            #current xpath token
            current_xpath = None

            while 1:
                try:
                    token = next()
                    if token[0] == "/":
                        token = next()

                        #Ignore attribue element (xpath=//sg/@name)
                        if token[0] == "@":
                            attr_xpath = True
                            continue

                        index = xpath.rfind("/%s" %token[1])
                        if index >= 0:
                            parent_xpath = "%s" %(xpath[:index])

                            #Get xpath assume suffix is leaf
                            next_index = xpath.find("/", len(parent_xpath) + 1)
                            if next_index>0:
                                current_xpath = xpath[0:next_index]
                            else:
                                #Last leaf
                                current_xpath = xpath

                            if root is None:
                                root = ET.Element(key_to_xml(token[1]))
                                current_elemment = root
                                self.mapparentelem["/%s" %token[1]] = current_elemment
                            else:
                                current_elemment = self._buildNode(current_xpath)
                    elif token[0] == "[":
                        attributes = self._transformAttr(next, token)
                        if len(attributes) > 0:
                            current_elemment.attrib = attributes

                except StopIteration:
                    break

            if attr_xpath == False:
                current_elemment.text = value
Exemplo n.º 9
0
    def ExportXML(self, filename=None):
        """ Build element tree from xpaths """

        # Tree root node
        root = None

        #Map to store xpath and ElementXpath
        self.mapparentelem = {}
        ''' Select all rows of db to export '''
        for xpath in self.Iterators('/'):
            #Is attribute xpath? /a/b/c@name => attr name
            attr_xpath = False

            try:
                value = str(self.Read(xpath))
            except SystemError, e:
                print "Cannot read [%s], error %s" % (xpath, str(e))
                continue
            next = iter(ElementPath.xpath_tokenizer(xpath)).next

            #For each leaf node on xpath
            current_elemment = root

            #parent xpath
            parent_xpath = None

            #current xpath token
            current_xpath = None

            while 1:
                try:
                    token = next()
                    if token[0] == "/":
                        token = next()

                        #Ignore attribue element (xpath=//sg/@name)
                        if token[0] == "@":
                            attr_xpath = True
                            continue

                        index = xpath.rfind("/%s" % token[1])
                        if index >= 0:
                            parent_xpath = "%s" % (xpath[:index])

                            #Get xpath assume suffix is leaf
                            next_index = xpath.find("/", len(parent_xpath) + 1)
                            if next_index > 0:
                                current_xpath = xpath[0:next_index]
                            else:
                                #Last leaf
                                current_xpath = xpath

                            if root is None:
                                root = ET.Element(key_to_xml(token[1]))
                                current_elemment = root
                                self.mapparentelem["/%s" %
                                                   token[1]] = current_elemment
                            else:
                                current_elemment = self._buildNode(
                                    current_xpath)
                    elif token[0] == "[":
                        attributes = self._transformAttr(next, token)
                        if len(attributes) > 0:
                            current_elemment.attrib = attributes

                except StopIteration:
                    break

            if attr_xpath == False:
                current_elemment.text = value