Handle types with 'range' or 'length' restrictions.

        `tchain` is the chain of type definitions from which the
        ranges may need to be extracted. `rangekw` is the statement
        keyword determining the range type (either 'range' or
        'length'). `gen_data` is a function that generates the
        output schema node (a RELAX NG <data> pattern).

def type_with_ranges(self, tchain, p_elem, rangekw, gen_data):
        """Handle types with 'range' or 'length' restrictions.

        `tchain` is the chain of type definitions from which the
        ranges may need to be extracted. `rangekw` is the statement
        keyword determining the range type (either 'range' or
        'length'). `gen_data` is a function that generates the
        output schema node (a RELAX NG <data> pattern).
        """
        ranges = self.get_ranges(tchain, rangekw)
        if not ranges: return p_elem.subnode(gen_data())
        if len(ranges) > 1:
            p_elem = SchemaNode.choice(p_elem)
            p_elem.occur = 2
        for r in ranges:
            d_elem = gen_data()
            for p in self.range_params(r, rangekw):
                d_elem.subnode(p)
            p_elem.subnode(d_elem)