File indexing completed on 2023-03-17 10:53:54
0001 from __future__ import print_function
0002 import xml.dom.minidom as dom
0003 import sys, os, optparse
0004
0005 class OptionParser(optparse.OptionParser):
0006 """
0007 OptionParser is main class to parse options.
0008 """
0009 def __init__(self):
0010 optparse.OptionParser.__init__(self, usage="%prog --help or %prog [options] file", version="%prog 0.0.1", conflict_handler="resolve")
0011 self.add_option("--src", action="store", type="string", dest="src", help="specify source XML file")
0012 self.add_option("--min", action="store", type="int", dest="min", help="Minimum length to measure")
0013 self.add_option("--max", action="store", type="int", dest="max", help="Maximum length to measure")
0014 self.add_option("--cid", action="store", type="int", dest="cid", help="Apply combination ID")
0015 self.add_option("--xsd", action="store_true", dest="xsd", help="Create XML Schema fragment")
0016
0017 def read_data():
0018 print("Reading histogram file")
0019 n = 0
0020 histos = srcdoc.getElementsByTagName("Histogram")
0021 for histo in histos:
0022 h = []
0023 for key in histo.childNodes:
0024 if key.nodeType == key.ELEMENT_NODE:
0025 name = key.localName
0026 value = key.childNodes[0].nodeValue
0027 found = 0
0028
0029 if name not in elements:
0030 elements[name] = {'type': '', 'count': 0}
0031 elements[name]['count'] = elements[name]['count'] + 1
0032
0033 try:
0034 i = int(value)
0035 if elements[name]['type'] == '':
0036 elements[name]['type'] = 'xs:integer'
0037 except ValueError:
0038 try:
0039 i = float(value)
0040 if elements[name]['type'] in ('', 'xs:integer'):
0041 elements[name]['type'] = 'xs:double'
0042 except ValueError:
0043 elements[name]['type'] = 'xs:string'
0044
0045 for k in keys.keys():
0046 if keys[k]['name'] == name and keys[k]['value'] == value:
0047 keys[k]['count'] = keys[k]['count'] + 1
0048 h.append(k)
0049 found = 1
0050 break
0051 if found == 0:
0052 keys[n] = {'name': name, 'value': value, 'count': 1}
0053 h.append(n)
0054 n += 1
0055 h.sort()
0056 histograms.append(h)
0057
0058 def create_xsd():
0059 for k in keys.keys():
0060 name = keys[k]['name']
0061
0062 root = resdoc.createElement("xs:complexType")
0063 root.setAttribute("name", "HistogramType")
0064 resdoc.appendChild(root)
0065 seq = resdoc.createElement("xs:all")
0066 root.appendChild(seq)
0067 for e in sorted(elements.keys()):
0068 el = resdoc.createElement("xs:element")
0069 el.setAttribute("name", e)
0070 el.setAttribute("type", elements[e]['type'])
0071 if elements[e]['count'] < len(histograms):
0072 el.setAttribute("minOccurs", '0')
0073 el.setAttribute("maxOccurs", '1')
0074 seq.appendChild(el)
0075
0076 def create_declaration(cid):
0077 co = comb[cid]
0078 print("Declaration to apply:", co)
0079 for k in comb[cid]:
0080 print(keys[k]['name'], '=', keys[k]['value'])
0081
0082 def cexists(s, c):
0083 d = len(c)
0084 for v1 in s:
0085 for v2 in c:
0086 if v1 == v2:
0087 d = d - 1
0088 return (d == 0)
0089
0090 def ccopy(a):
0091 r = []
0092 for v in a:
0093 r.append(v)
0094 return r
0095
0096 def kpermutation(vfrom, vto, min, max):
0097 vto = vto + 1
0098 queue = []
0099 for i in range(vfrom, vto):
0100 for j in range(i, vto):
0101 queue.append(j)
0102 if len(queue) >= min and len(queue) <= max:
0103 yield queue
0104 queue = []
0105
0106 def compute(min, max):
0107 print("Computing permutations")
0108 for v in kpermutation(0, len(keys), min, max):
0109 ci = -1
0110 for h in histograms:
0111 if cexists(h, v):
0112 if ci == -1:
0113 ci = len(comb)
0114 comb[ci] = ccopy(v)
0115 results[ci] = [h]
0116 else:
0117 results[ci].append(h)
0118
0119 def priorities():
0120 for ci in comb.keys():
0121 l = len(results[ci])
0122 if l == 1:
0123 continue
0124 if l not in prior:
0125 prior[l] = [ci]
0126 else:
0127 prior[l].append(ci)
0128
0129 if __name__ == "__main__":
0130
0131 optManager = OptionParser()
0132 (opts, args) = optManager.parse_args()
0133 opts = opts.__dict__
0134
0135 if opts['src'] in ('', None):
0136 print("You must specify a valid source xml file")
0137 sys.exit(0)
0138
0139 resdoc = dom.Document()
0140 srcdoc = dom.parse(opts['src'])
0141
0142 histograms = []
0143 keys = {}
0144 results = {}
0145 comb = {}
0146 prior = {}
0147 elements = {}
0148 len_min = 1000000
0149 len_max = 0
0150
0151 read_data()
0152
0153 if opts['xsd'] != None:
0154
0155 create_xsd()
0156 print(resdoc.toprettyxml())
0157
0158 else:
0159
0160 for h in histograms:
0161 if len(h) > len_max: len_max = len(h)
0162 if len(h) < len_min: len_min = len(h)
0163 print("Computed len: min = ", len_min, ", max = ", len_max)
0164
0165 min = 2
0166 if opts['min'] not in (0, None): min = opts['min']
0167 max = len_max
0168 if opts['max'] not in (0, None): max = opts['max']
0169 print("Computing lens from", min, " to ", max)
0170
0171 compute(min, max)
0172 priorities()
0173
0174 for pi in sorted(prior.keys()):
0175 print(pi, "=", prior[pi])
0176
0177 if opts['cid'] != None:
0178 create_declaration(opts['cid'])