author  Andrey Skvortsov <andrej.skvortzov@gmail.com> 
Mon, 21 Aug 2017 21:55:18 +0300  
changeset 1782  5b6ad7a7fd9d 
parent 1780  c52d1460cea8 
child 1826  91796f408540 
permissions  rwrr 
814  1 
#!/usr/bin/env python 
2 
# * coding: utf8 * 

3 

1571
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1375
diff
changeset

4 
# This file is part of Beremiz, a Integrated Development Environment for 
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1375
diff
changeset

5 
# programming IEC 611313 automates supporting plcopen standard and CanFestival. 
814  6 
# 
1571
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1375
diff
changeset

7 
# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD 
814  8 
# 
1571
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1375
diff
changeset

9 
# See COPYING file for copyrights details. 
814  10 
# 
1571
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1375
diff
changeset

11 
# This program is free software; you can redistribute it and/or 
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1375
diff
changeset

12 
# modify it under the terms of the GNU General Public License 
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1375
diff
changeset

13 
# as published by the Free Software Foundation; either version 2 
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1375
diff
changeset

14 
# of the License, or (at your option) any later version. 
814  15 
# 
1571
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1375
diff
changeset

16 
# This program is distributed in the hope that it will be useful, 
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1375
diff
changeset

17 
# but WITHOUT ANY WARRANTY; without even the implied warranty of 
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1375
diff
changeset

18 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1375
diff
changeset

19 
# GNU General Public License for more details. 
814  20 
# 
1571
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1375
diff
changeset

21 
# You should have received a copy of the GNU General Public License 
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1375
diff
changeset

22 
# along with this program; if not, write to the Free Software 
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1375
diff
changeset

23 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 021101301, USA. 
814  24 

1732
94ffe74e6895
cleanup: fix PEP8 E401 multiple imports on one line
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1730
diff
changeset

25 
import os 
94ffe74e6895
cleanup: fix PEP8 E401 multiple imports on one line
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1730
diff
changeset

26 
import re 
814  27 
import datetime 
28 
from xml.dom import minidom 

29 
from types import * 

30 

31 
from xmlclass import * 

32 

1736
7e61baa047f0
cleanup: fix PEP8 E302 expected 2 blank lines, found 1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1734
diff
changeset

33 

814  34 
def GenerateDictFacets(facets): 
35 
return dict([(name, (None, False)) for name in facets]) 

36 

1736
7e61baa047f0
cleanup: fix PEP8 E302 expected 2 blank lines, found 1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1734
diff
changeset

37 

814  38 
def GenerateSimpleTypeXMLText(function): 
39 
def generateXMLTextMethod(value, name=None, indent=0): 

40 
text = "" 

41 
if name is not None: 

42 
ind1, ind2 = getIndent(indent, name) 

43 
text += ind1 + "<%s>" % name 

44 
text += function(value) 

45 
if name is not None: 

46 
text += "</%s>\n" % name 

47 
return text 

48 
return generateXMLTextMethod 

49 

1736
7e61baa047f0
cleanup: fix PEP8 E302 expected 2 blank lines, found 1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1734
diff
changeset

50 

1373
4278d5c1e414
Fixed bug when graphic element position and size and connection points are decimal
Laurent Bessard
parents:
1322
diff
changeset

51 
def GenerateFloatXMLText(extra_values=[], decimal=None): 
1374
1eefc427419f
Fixed bug with decimal value string formatting
Laurent Bessard
parents:
1373
diff
changeset

52 
float_format = (lambda x: "{:.{width}f}".format(x, width=decimal).rstrip('0') 
1eefc427419f
Fixed bug with decimal value string formatting
Laurent Bessard
parents:
1373
diff
changeset

53 
if decimal is not None else str) 
1750
acf02488f37f
cleanup: fix PEP8 E306 expected 1 blank line before a nested definition, found X
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1749
diff
changeset

54 

814  55 
def generateXMLTextMethod(value, name=None, indent=0): 
56 
text = "" 

57 
if name is not None: 

58 
ind1, ind2 = getIndent(indent, name) 

59 
text += ind1 + "<%s>" % name 

1375
dc94c71a2f25
Fixed bug with decimal value string formatting
Laurent Bessard
parents:
1374
diff
changeset

60 
if isinstance(value, IntType): 
dc94c71a2f25
Fixed bug with decimal value string formatting
Laurent Bessard
parents:
1374
diff
changeset

61 
text += str(value) 
dc94c71a2f25
Fixed bug with decimal value string formatting
Laurent Bessard
parents:
1374
diff
changeset

62 
elif value in extra_values or value % 1 != 0: 
1373
4278d5c1e414
Fixed bug when graphic element position and size and connection points are decimal
Laurent Bessard
parents:
1322
diff
changeset

63 
text += float_format(value) 
814  64 
else: 
1375
dc94c71a2f25
Fixed bug with decimal value string formatting
Laurent Bessard
parents:
1374
diff
changeset

65 
text += "{:.0f}".format(value) 
814  66 
if name is not None: 
67 
text += "</%s>\n" % name 

68 
return text 

69 
return generateXMLTextMethod 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

70 

1749
d73b64672238
cleanup: fix PEP8 E305 expected 2 blank lines after class or function definition
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1744
diff
changeset

71 

814  72 
DEFAULT_FACETS = GenerateDictFacets(["pattern", "whiteSpace", "enumeration"]) 
73 
NUMBER_FACETS = GenerateDictFacets(DEFAULT_FACETS.keys() + ["maxInclusive", "maxExclusive", "minInclusive", "minExclusive"]) 

74 
DECIMAL_FACETS = GenerateDictFacets(NUMBER_FACETS.keys() + ["totalDigits", "fractionDigits"]) 

75 
STRING_FACETS = GenerateDictFacets(DEFAULT_FACETS.keys() + ["length", "minLength", "maxLength"]) 

76 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

77 
ALL_FACETS = ["pattern", "whiteSpace", "enumeration", "maxInclusive", 
1768
691083b5682a
cleanup: fix PEP8 E128 continuation line underindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset

78 
"maxExclusive", "minInclusive", "minExclusive", "totalDigits", 
691083b5682a
cleanup: fix PEP8 E128 continuation line underindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset

79 
"fractionDigits", "length", "minLength", "maxLength"] 
814  80 

81 

1782
5b6ad7a7fd9d
cleanup: fix PEP8 E265 block comment should start with '# '
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1780
diff
changeset

82 
#  
814  83 
# Structure reducing functions 
1782
5b6ad7a7fd9d
cleanup: fix PEP8 E265 block comment should start with '# '
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1780
diff
changeset

84 
#  
814  85 

86 

87 
# Documentation elements 

88 

89 
def ReduceAppInfo(factory, attributes, elements): 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

90 
return {"type": "appinfo", "source": attributes.get("source", None), 
814  91 
"content": "\n".join(elements)} 
92 

93 

94 
def ReduceDocumentation(factory, attributes, elements): 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

95 
return {"type": "documentation", "source": attributes.get("source", None), 
814  96 
"language": attributes.get("lang", "any"), "content": "\n".join(elements)} 
97 

98 

99 
def ReduceAnnotation(factory, attributes, elements): 

100 
annotations, children = factory.ReduceElements(elements) 

101 
annotation = {"type": "annotation", "appinfo": [], "documentation": {}} 

102 
for child in children: 

103 
if child["type"] == "appinfo": 

104 
annotation["appinfo"].append((child["source"], child["content"])) 

105 
elif child["type"] == "documentation": 

106 
if child["source"] is not None: 

1734
750eeb7230a1
cleanup: fix some PEP8 E228 missing whitespace around modulo operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1732
diff
changeset

107 
text = "(source: %(source)s):\n%(content)s\n\n" % child 
814  108 
else: 
109 
text = child["content"] + "\n\n" 

1763
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

110 
if not child["language"] in annotation["documentation"]: 
814  111 
annotation["documentation"] = text 
112 
else: 

113 
annotation["documentation"] += text 

114 
return annotation 

115 

116 
# Simple type elements 

117 

1736
7e61baa047f0
cleanup: fix PEP8 E302 expected 2 blank lines, found 1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1734
diff
changeset

118 

814  119 
def GenerateFacetReducing(facetname, canbefixed): 
120 
def ReduceFacet(factory, attributes, elements): 

121 
annotations, children = factory.ReduceElements(elements) 

1763
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

122 
if "value" in attributes: 
814  123 
facet = {"type": facetname, "value": attributes["value"], "doc": annotations} 
124 
if canbefixed: 

125 
facet["fixed"] = attributes.get("fixed", False) 

126 
return facet 

127 
raise ValueError("A value must be defined for the \"%s\" facet!" % facetname) 

128 
return ReduceFacet 

129 

130 

131 
def ReduceList(factory, attributes, elements): 

132 
annotations, children = factory.ReduceElements(elements) 

133 
list = {"type": "list", "itemType": attributes.get("itemType", None), "doc": annotations} 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

134 

814  135 
if len(children) > 0 and children[0]["type"] == SIMPLETYPE: 
136 
if list["itemType"] is None: 

137 
list["itemType"] = children[0] 

138 
else: 

139 
raise ValueError("Only one base type can be defined for restriction!") 

140 
if list["itemType"] is None: 

141 
raise ValueError("No base type has been defined for list!") 

142 
return list 

143 

144 

145 
def ReduceUnion(factory, attributes, elements): 

146 
annotations, children = factory.ReduceElements(elements) 

147 
union = {"type": "union", "memberTypes": attributes.get("memberTypes", []), "doc": annotations} 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

148 

814  149 
for child in children: 
150 
if child["type"] == SIMPLETYPE: 

151 
union["memberTypes"].appendchild 

152 
if len(union["memberTypes"]) == 0: 

153 
raise ValueError("No base type has been defined for union!") 

154 
return union 

155 

156 

157 
def CreateSimpleType(factory, attributes, typeinfos): 

158 
# Initialize type informations 

159 
facets = {} 

160 
simpleType = {"type": SIMPLETYPE, "final": attributes.get("final", [])} 

1763
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

161 
if "name" in attributes: 
814  162 
simpleType["name"] = attributes["name"] 
1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

163 

814  164 
if typeinfos["type"] in ["restriction", "extension"]: 
165 
# Search for base type definition 

166 
if isinstance(typeinfos["base"], (StringType, UnicodeType)): 

167 
basetypeinfos = factory.FindSchemaElement(typeinfos["base"], SIMPLETYPE) 

168 
if basetypeinfos is None: 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

169 
raise "\"%s\" isn't defined!" % typeinfos["base"] 
814  170 
else: 
171 
basetypeinfos = typeinfos["base"] 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

172 

814  173 
# Check that base type is a simple type 
174 
if basetypeinfos["type"] != SIMPLETYPE: 

175 
raise ValueError("Base type given isn't a simpleType!") 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

176 

814  177 
simpleType["basename"] = basetypeinfos["basename"] 
1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

178 

814  179 
# Check that derivation is allowed 
1763
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

180 
if "final" in basetypeinfos: 
814  181 
if "#all" in basetypeinfos["final"]: 
182 
raise ValueError("Base type can't be derivated!") 

183 
if "restriction" in basetypeinfos["final"] and typeinfos["type"] == "restriction": 

184 
raise ValueError("Base type can't be derivated by restriction!") 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

185 

814  186 
# Extract simple type facets 
187 
for facet in typeinfos.get("facets", []): 

188 
facettype = facet["type"] 

1775
b45f2768fab1
cleanup: fix PEP8 E713 test for membership should be 'not in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1774
diff
changeset

189 
if facettype not in basetypeinfos["facets"]: 
814  190 
raise ValueError("\"%s\" facet can't be defined for \"%s\" type!" % (facettype, type)) 
191 
elif basetypeinfos["facets"][facettype][1]: 

192 
raise ValueError("\"%s\" facet is fixed on base type!" % facettype) 

193 
value = facet["value"] 

194 
basevalue = basetypeinfos["facets"][facettype][0] 

195 
if facettype in ["enumeration", "pattern"]: 

196 
value = basetypeinfos["extract"](value, False) 

197 
if len(facets) == 0: 

198 
facets[facettype] = ([value], False) 

199 
continue 

200 
elif facets.keys() == [facettype]: 

201 
facets[facettype][0].append(value) 

202 
continue 

203 
else: 

204 
raise ValueError("\"%s\" facet can't be defined with another facet type!" % facettype) 

1763
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

205 
elif "enumeration" in facets: 
814  206 
raise ValueError("\"enumeration\" facet can't be defined with another facet type!") 
1763
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

207 
elif "pattern" in facets: 
814  208 
raise ValueError("\"pattern\" facet can't be defined with another facet type!") 
1763
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

209 
elif facettype in facets: 
814  210 
raise ValueError("\"%s\" facet can't be defined two times!" % facettype) 
211 
elif facettype == "length": 

1763
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

212 
if "minLength" in facets: 
814  213 
raise ValueError("\"length\" and \"minLength\" facets can't be defined at the same time!") 
1763
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

214 
if "maxLength" in facets: 
814  215 
raise ValueError("\"length\" and \"maxLength\" facets can't be defined at the same time!") 
216 
try: 

217 
value = int(value) 

1780
c52d1460cea8
cleanup: fix PEP8 E722 do not use bare except'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1776
diff
changeset

218 
except Exception: 
814  219 
raise ValueError("\"length\" must be an integer!") 
220 
if value < 0: 

221 
raise ValueError("\"length\" can't be negative!") 

222 
elif basevalue is not None and basevalue != value: 

223 
raise ValueError("\"length\" can't be different from \"length\" defined in base type!") 

224 
elif facettype == "minLength": 

1763
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

225 
if "length" in facets: 
814  226 
raise ValueError("\"length\" and \"minLength\" facets can't be defined at the same time!") 
227 
try: 

228 
value = int(value) 

1780
c52d1460cea8
cleanup: fix PEP8 E722 do not use bare except'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1776
diff
changeset

229 
except Exception: 
814  230 
raise ValueError("\"minLength\" must be an integer!") 
231 
if value < 0: 

232 
raise ValueError("\"minLength\" can't be negative!") 

1763
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

233 
elif "maxLength" in facets and value > facets["maxLength"]: 
814  234 
raise ValueError("\"minLength\" must be lesser than or equal to \"maxLength\"!") 
235 
elif basevalue is not None and basevalue < value: 

236 
raise ValueError("\"minLength\" can't be lesser than \"minLength\" defined in base type!") 

237 
elif facettype == "maxLength": 

1763
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

238 
if "length" in facets: 
814  239 
raise ValueError("\"length\" and \"maxLength\" facets can't be defined at the same time!") 
240 
try: 

241 
value = int(value) 

1780
c52d1460cea8
cleanup: fix PEP8 E722 do not use bare except'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1776
diff
changeset

242 
except Exception: 
814  243 
raise ValueError("\"maxLength\" must be an integer!") 
244 
if value < 0: 

245 
raise ValueError("\"maxLength\" can't be negative!") 

1763
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

246 
elif "minLength" in facets and value < facets["minLength"]: 
814  247 
raise ValueError("\"minLength\" must be lesser than or equal to \"maxLength\"!") 
248 
elif basevalue is not None and basevalue > value: 

249 
raise ValueError("\"maxLength\" can't be greater than \"maxLength\" defined in base type!") 

250 
elif facettype == "minInclusive": 

1763
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

251 
if "minExclusive" in facets: 
814  252 
raise ValueError("\"minExclusive\" and \"minInclusive\" facets can't be defined at the same time!") 
253 
value = basetypeinfos["extract"](facet["value"], False) 

1763
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

254 
if "maxInclusive" in facets and value > facets["maxInclusive"][0]: 
814  255 
raise ValueError("\"minInclusive\" must be lesser than or equal to \"maxInclusive\"!") 
1763
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

256 
elif "maxExclusive" in facets and value >= facets["maxExclusive"][0]: 
814  257 
raise ValueError("\"minInclusive\" must be lesser than \"maxExclusive\"!") 
258 
elif facettype == "minExclusive": 

1763
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

259 
if "minInclusive" in facets: 
814  260 
raise ValueError("\"minExclusive\" and \"minInclusive\" facets can't be defined at the same time!") 
261 
value = basetypeinfos["extract"](facet["value"], False) 

1763
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

262 
if "maxInclusive" in facets and value >= facets["maxInclusive"][0]: 
814  263 
raise ValueError("\"minExclusive\" must be lesser than \"maxInclusive\"!") 
1763
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

264 
elif "maxExclusive" in facets and value >= facets["maxExclusive"][0]: 
814  265 
raise ValueError("\"minExclusive\" must be lesser than \"maxExclusive\"!") 
266 
elif facettype == "maxInclusive": 

1763
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

267 
if "maxExclusive" in facets: 
814  268 
raise ValueError("\"maxExclusive\" and \"maxInclusive\" facets can't be defined at the same time!") 
269 
value = basetypeinfos["extract"](facet["value"], False) 

1763
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

270 
if "minInclusive" in facets and value < facets["minInclusive"][0]: 
814  271 
raise ValueError("\"minInclusive\" must be lesser than or equal to \"maxInclusive\"!") 
1763
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

272 
elif "minExclusive" in facets and value <= facets["minExclusive"][0]: 
814  273 
raise ValueError("\"minExclusive\" must be lesser than \"maxInclusive\"!") 
274 
elif facettype == "maxExclusive": 

1763
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

275 
if "maxInclusive" in facets: 
814  276 
raise ValueError("\"maxExclusive\" and \"maxInclusive\" facets can't be defined at the same time!") 
277 
value = basetypeinfos["extract"](facet["value"], False) 

1763
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

278 
if "minInclusive" in facets and value <= facets["minInclusive"][0]: 
814  279 
raise ValueError("\"minInclusive\" must be lesser than \"maxExclusive\"!") 
1763
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

280 
elif "minExclusive" in facets and value <= facets["minExclusive"][0]: 
814  281 
raise ValueError("\"minExclusive\" must be lesser than \"maxExclusive\"!") 
282 
elif facettype == "whiteSpace": 

283 
if basevalue == "collapse" and value in ["preserve", "replace"] or basevalue == "replace" and value == "preserve": 

1757
0de89da92ee0
cleanup: fix PEP8 E111 indentation is not a multiple of four
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1750
diff
changeset

284 
raise ValueError("\"whiteSpace\" is incompatible with \"whiteSpace\" defined in base type!") 
814  285 
elif facettype == "totalDigits": 
1763
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

286 
if "fractionDigits" in facets and value <= facets["fractionDigits"][0]: 
814  287 
raise ValueError("\"fractionDigits\" must be lesser than or equal to \"totalDigits\"!") 
288 
elif basevalue is not None and value > basevalue: 

289 
raise ValueError("\"totalDigits\" can't be greater than \"totalDigits\" defined in base type!") 

290 
elif facettype == "fractionDigits": 

1763
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

291 
if "totalDigits" in facets and value <= facets["totalDigits"][0]: 
814  292 
raise ValueError("\"fractionDigits\" must be lesser than or equal to \"totalDigits\"!") 
293 
elif basevalue is not None and value > basevalue: 

294 
raise ValueError("\"totalDigits\" can't be greater than \"totalDigits\" defined in base type!") 

295 
facets[facettype] = (value, facet.get("fixed", False)) 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

296 

64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

297 
# Report not redefined facet from base type to new created type 
814  298 
for facettype, facetvalue in basetypeinfos["facets"].items(): 
1775
b45f2768fab1
cleanup: fix PEP8 E713 test for membership should be 'not in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1774
diff
changeset

299 
if facettype not in facets: 
814  300 
facets[facettype] = facetvalue 
1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

301 

814  302 
# Generate extract value for new created type 
303 
def ExtractSimpleTypeValue(attr, extract=True): 

304 
value = basetypeinfos["extract"](attr, extract) 

305 
for facetname, (facetvalue, facetfixed) in facets.items(): 

306 
if facetvalue is not None: 

307 
if facetname == "enumeration" and value not in facetvalue: 

308 
raise ValueError("\"%s\" not in enumerated values" % value) 

309 
elif facetname == "length" and len(value) != facetvalue: 

310 
raise ValueError("value must have a length of %d" % facetvalue) 

311 
elif facetname == "minLength" and len(value) < facetvalue: 

312 
raise ValueError("value must have a length of %d at least" % facetvalue) 

313 
elif facetname == "maxLength" and len(value) > facetvalue: 

314 
raise ValueError("value must have a length of %d at most" % facetvalue) 

315 
elif facetname == "minInclusive" and value < facetvalue: 

316 
raise ValueError("value must be greater than or equal to %s" % str(facetvalue)) 

317 
elif facetname == "minExclusive" and value <= facetvalue: 

318 
raise ValueError("value must be greater than %s" % str(facetvalue)) 

319 
elif facetname == "maxInclusive" and value > facetvalue: 

320 
raise ValueError("value must be lesser than or equal to %s" % str(facetvalue)) 

1774
ac0fe8aabb5e
cleanup: fix PEP8 E272 multiple spaces before keyword
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1768
diff
changeset

321 
elif facetname == "maxExclusive" and value >= facetvalue: 
814  322 
raise ValueError("value must be lesser than %s" % str(facetvalue)) 
323 
elif facetname == "pattern": 

324 
model = re.compile("(?:%s)?$" % "".join(map(lambda x: "(?:%s)" % x, facetvalue))) 

325 
result = model.match(value) 

326 
if result is None: 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

327 
if len(facetvalue) > 1: 
814  328 
raise ValueError("value doesn't follow any of the patterns %s" % ",".join(facetvalue)) 
329 
else: 

330 
raise ValueError("value doesn't follow the pattern %s" % facetvalue[0]) 

331 
elif facetname == "whiteSpace": 

332 
if facetvalue == "replace": 

333 
value = GetNormalizedString(value, False) 

334 
elif facetvalue == "collapse": 

335 
value = GetToken(value, False) 

336 
return value 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

337 

814  338 
def CheckSimpleTypeValue(value): 
339 
for facetname, (facetvalue, facetfixed) in facets.items(): 

340 
if facetvalue is not None: 

341 
if facetname == "enumeration" and value not in facetvalue: 

342 
return False 

343 
elif facetname == "length" and len(value) != facetvalue: 

344 
return False 

345 
elif facetname == "minLength" and len(value) < facetvalue: 

346 
return False 

347 
elif facetname == "maxLength" and len(value) > facetvalue: 

348 
return False 

349 
elif facetname == "minInclusive" and value < facetvalue: 

350 
return False 

351 
elif facetname == "minExclusive" and value <= facetvalue: 

352 
return False 

353 
elif facetname == "maxInclusive" and value > facetvalue: 

354 
return False 

1774
ac0fe8aabb5e
cleanup: fix PEP8 E272 multiple spaces before keyword
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1768
diff
changeset

355 
elif facetname == "maxExclusive" and value >= facetvalue: 
814  356 
return False 
357 
elif facetname == "pattern": 

358 
model = re.compile("(?:%s)?$" % "".join(map(lambda x: "(?:%s)" % x, facetvalue))) 

359 
result = model.match(value) 

360 
if result is None: 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

361 
if len(facetvalue) > 1: 
814  362 
raise ValueError("value doesn't follow any of the patterns %s" % ",".join(facetvalue)) 
363 
else: 

364 
raise ValueError("value doesn't follow the pattern %s" % facetvalue[0]) 

365 
return True 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

366 

814  367 
def SimpleTypeInitialValue(): 
368 
for facetname, (facetvalue, facetfixed) in facets.items(): 

369 
if facetvalue is not None: 

370 
if facetname == "enumeration": 

371 
return facetvalue[0] 

372 
elif facetname == "length": 

373 
return " "*facetvalue 

374 
elif facetname == "minLength": 

375 
return " "*minLength 

376 
elif facetname == "minInclusive" and facetvalue > 0: 

377 
return facetvalue 

378 
elif facetname == "minExclusive" and facetvalue >= 0: 

379 
return facetvalue + 1 

380 
elif facetname == "maxInclusive" and facetvalue < 0: 

381 
return facetvalue 

1774
ac0fe8aabb5e
cleanup: fix PEP8 E272 multiple spaces before keyword
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1768
diff
changeset

382 
elif facetname == "maxExclusive" and facetvalue <= 0: 
814  383 
return facetvalue  1 
384 
return basetypeinfos["initial"]() 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

385 

814  386 
GenerateSimpleType = basetypeinfos["generate"] 
1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

387 

814  388 
elif typeinfos["type"] == "list": 
389 
# Search for item type definition 

390 
if isinstance(typeinfos["itemType"], (StringType, UnicodeType)): 

391 
itemtypeinfos = factory.FindSchemaElement(typeinfos["itemType"], SIMPLETYPE) 

392 
if itemtypeinfos is None: 

393 
raise "\"%s\" isn't defined!" % typeinfos["itemType"] 

394 
else: 

395 
itemtypeinfos = typeinfos["itemType"] 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

396 

814  397 
# Check that item type is a simple type 
398 
if itemtypeinfos["type"] != SIMPLETYPE: 

1765
ccf59c1f0b45
cleanup: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset

399 
raise ValueError("Item type given isn't a simpleType!") 
1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

400 

814  401 
simpleType["basename"] = "list" 
1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

402 

814  403 
# Check that derivation is allowed 
1763
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

404 
if "final" in itemtypeinfos: 
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

405 
if "#all" in itemtypeinfos["final"]: 
814  406 
raise ValueError("Item type can't be derivated!") 
1763
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

407 
if "list" in itemtypeinfos["final"]: 
814  408 
raise ValueError("Item type can't be derivated by list!") 
1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

409 

814  410 
# Generate extract value for new created type 
1744
69dfdb26f600
cleanup: fix PEP8 E251 unexpected spaces around keyword / parameter equals
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1743
diff
changeset

411 
def ExtractSimpleTypeValue(attr, extract=True): 
814  412 
values = [] 
413 
for value in GetToken(attr, extract).split(" "): 

414 
values.append(itemtypeinfos["extract"](value, False)) 

415 
return values 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

416 

814  417 
def CheckSimpleTypeValue(value): 
418 
for item in value: 

419 
result = itemtypeinfos["check"](item) 

420 
if not result: 

421 
return result 

422 
return True 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

423 

1762
fcc406143e5b
cleanup: fix PEP8 E731 do not assign a lambda expression, use a def
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1757
diff
changeset

424 
def SimpleTypeInitialValue(): 
fcc406143e5b
cleanup: fix PEP8 E731 do not assign a lambda expression, use a def
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1757
diff
changeset

425 
return [] 
1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

426 

814  427 
GenerateSimpleType = GenerateSimpleTypeXMLText(lambda x: " ".join(map(itemtypeinfos["generate"], x))) 
1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

428 

814  429 
facets = GenerateDictFacets(["length", "maxLength", "minLength", "enumeration", "pattern"]) 
430 
facets["whiteSpace"] = ("collapse", False) 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

431 

814  432 
elif typeinfos["type"] == "union": 
433 
# Search for member types definition 

434 
membertypesinfos = [] 

435 
for membertype in typeinfos["memberTypes"]: 

436 
if isinstance(membertype, (StringType, UnicodeType)): 

437 
infos = factory.FindSchemaElement(membertype, SIMPLETYPE) 

438 
if infos is None: 

439 
raise ValueError("\"%s\" isn't defined!" % membertype) 

440 
else: 

441 
infos = membertype 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

442 

814  443 
# Check that member type is a simple type 
444 
if infos["type"] != SIMPLETYPE: 

445 
raise ValueError("Member type given isn't a simpleType!") 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

446 

814  447 
# Check that derivation is allowed 
1763
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

448 
if "final" in infos: 
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

449 
if "#all" in infos["final"]: 
814  450 
raise ValueError("Item type can't be derivated!") 
1763
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

451 
if "union" in infos["final"]: 
814  452 
raise ValueError("Member type can't be derivated by union!") 
1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

453 

814  454 
membertypesinfos.append(infos) 
1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

455 

814  456 
simpleType["basename"] = "union" 
1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

457 

814  458 
# Generate extract value for new created type 
1744
69dfdb26f600
cleanup: fix PEP8 E251 unexpected spaces around keyword / parameter equals
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1743
diff
changeset

459 
def ExtractSimpleTypeValue(attr, extract=True): 
814  460 
if extract: 
461 
value = GetAttributeValue(attr) 

462 
else: 

463 
value = attr 

464 
for infos in membertypesinfos: 

465 
try: 

466 
return infos["extract"](attr, False) 

1780
c52d1460cea8
cleanup: fix PEP8 E722 do not use bare except'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1776
diff
changeset

467 
except Exception: 
814  468 
pass 
469 
raise ValueError("\"%s\" isn't valid for type defined for union!") 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

470 

814  471 
def CheckSimpleTypeValue(value): 
472 
for infos in membertypesinfos: 

473 
result = infos["check"](value) 

474 
if result: 

475 
return result 

476 
return False 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

477 

814  478 
SimpleTypeInitialValue = membertypesinfos[0]["initial"] 
1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

479 

814  480 
def GenerateSimpleTypeFunction(value): 
481 
if isinstance(value, BooleanType): 

482 
return {True: "true", False: "false"}[value] 

483 
else: 

484 
return str(value) 

485 
GenerateSimpleType = GenerateSimpleTypeXMLText(GenerateSimpleTypeFunction) 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

486 

814  487 
facets = GenerateDictFacets(["pattern", "enumeration"]) 
1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

488 

814  489 
simpleType["facets"] = facets 
490 
simpleType["extract"] = ExtractSimpleTypeValue 

491 
simpleType["initial"] = SimpleTypeInitialValue 

492 
simpleType["check"] = CheckSimpleTypeValue 

493 
simpleType["generate"] = GenerateSimpleType 

494 
return simpleType 

495 

1736
7e61baa047f0
cleanup: fix PEP8 E302 expected 2 blank lines, found 1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1734
diff
changeset

496 

814  497 
def ReduceSimpleType(factory, attributes, elements): 
498 
# Reduce all the simple type children 

499 
annotations, children = factory.ReduceElements(elements) 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

500 

814  501 
simpleType = CreateSimpleType(factory, attributes, children[0]) 
502 
simpleType["doc"] = annotations 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

503 

814  504 
return simpleType 
505 

506 
# Complex type 

507 

1736
7e61baa047f0
cleanup: fix PEP8 E302 expected 2 blank lines, found 1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1734
diff
changeset

508 

814  509 
def ExtractAttributes(factory, elements, base=None): 
510 
attrs = [] 

511 
attrnames = {} 

512 
if base is not None: 

513 
basetypeinfos = factory.FindSchemaElement(base) 

514 
if not isinstance(basetypeinfos, (UnicodeType, StringType)) and basetypeinfos["type"] == COMPLEXTYPE: 

1740
b789b695b5c6
cleanup: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1739
diff
changeset

515 
attrnames = dict(map(lambda x: (x["name"], True), basetypeinfos["attributes"])) 
1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

516 

814  517 
for element in elements: 
518 
if element["type"] == ATTRIBUTE: 

519 
if attrnames.get(element["name"], False): 

520 
raise ValueError("\"%s\" attribute has been defined two times!" % element["name"]) 

521 
else: 

522 
attrnames[element["name"]] = True 

523 
attrs.append(element) 

524 
elif element["type"] == "attributeGroup": 

525 
attrgroup = factory.FindSchemaElement(element["ref"], ATTRIBUTESGROUP) 

526 
for attr in attrgroup["attributes"]: 

527 
if attrnames.get(attr["name"], False): 

528 
raise ValueError("\"%s\" attribute has been defined two times!" % attr["name"]) 

529 
else: 

530 
attrnames[attr["name"]] = True 

531 
attrs.append(attr) 

532 
elif element["type"] == "anyAttribute": 

533 
raise ValueError("\"anyAttribute\" element isn't supported yet!") 

534 
return attrs 

535 

536 

537 
def ReduceRestriction(factory, attributes, elements): 

538 
annotations, children = factory.ReduceElements(elements) 

539 
restriction = {"type": "restriction", "base": attributes.get("base", None), "facets": [], "doc": annotations} 

540 
if len(children) > 0 and children[0]["type"] == SIMPLETYPE: 

541 
if restriction["base"] is None: 

542 
restriction["base"] = children.pop(0) 

543 
else: 

544 
raise ValueError("Only one base type can be defined for restriction!") 

545 
if restriction["base"] is None: 

546 
raise ValueError("No base type has been defined for restriction!") 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

547 

814  548 
while len(children) > 0 and children[0]["type"] in ALL_FACETS: 
549 
restriction["facets"].append(children.pop(0)) 

550 
restriction["attributes"] = ExtractAttributes(factory, children, restriction["base"]) 

551 
return restriction 

552 

553 

554 
def ReduceExtension(factory, attributes, elements): 

555 
annotations, children = factory.ReduceElements(elements) 

1775
b45f2768fab1
cleanup: fix PEP8 E713 test for membership should be 'not in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1774
diff
changeset

556 
if "base" not in attributes: 
814  557 
raise ValueError("No base type has been defined for extension!") 
558 
extension = {"type": "extension", "attributes": [], "elements": [], "base": attributes["base"], "doc": annotations} 

559 
if len(children) > 0: 

560 
if children[0]["type"] in ["group", "all", CHOICE, "sequence"]: 

561 
group = children.pop(0) 

562 
if group["type"] in ["all", "sequence"]: 

563 
extension["elements"] = group["elements"] 

564 
extension["order"] = group["order"] 

565 
elif group["type"] == CHOICE: 

566 
content = group.copy() 

567 
content["name"] = "content" 

568 
extension["elements"].append(content) 

569 
elif group["type"] == "group": 

570 
elmtgroup = factory.FindSchemaElement(child["ref"], ELEMENTSGROUP) 

1763
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

571 
if "elements" in elmtgroup: 
814  572 
extension["elements"] = elmtgroup["elements"] 
573 
extension["order"] = elmtgroup["order"] 

574 
else: 

575 
content = elmtgroup.copy() 

576 
content["name"] = "content" 

577 
extension["elements"].append(content) 

578 
extension["attributes"] = ExtractAttributes(factory, children) 

579 
return extension 

580 

581 

582 
def ReduceSimpleContent(factory, attributes, elements): 

583 
annotations, children = factory.ReduceElements(elements) 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

584 

814  585 
simpleContent = children[0].copy() 
1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

586 

814  587 
basetypeinfos = factory.FindSchemaElement(simpleContent["base"]) 
588 
if basetypeinfos["type"] == SIMPLETYPE: 

589 
contenttypeinfos = simpleContent.copy() 

590 
simpleContent.pop("base") 

1767
c74815729afd
cleanup: fix PEP8 E127 continuation line overindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1765
diff
changeset

591 
elif (basetypeinfos["type"] == COMPLEXTYPE and 
c74815729afd
cleanup: fix PEP8 E127 continuation line overindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1765
diff
changeset

592 
len(basetypeinfos["elements"]) == 1 and 
c74815729afd
cleanup: fix PEP8 E127 continuation line overindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1765
diff
changeset

593 
basetypeinfos["elements"][0]["name"] == "content" and 
c74815729afd
cleanup: fix PEP8 E127 continuation line overindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1765
diff
changeset

594 
"elmt_type" in basetypeinfos["elements"][0] and 
c74815729afd
cleanup: fix PEP8 E127 continuation line overindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1765
diff
changeset

595 
basetypeinfos["elements"][0]["elmt_type"]["type"] == SIMPLETYPE): 
814  596 
contenttypeinfos = simpleContent.copy() 
597 
contenttypeinfos["base"] = basetypeinfos["elements"][0]["elmt_type"] 

598 
else: 

599 
raise ValueError("No compatible base type defined for simpleContent!") 

600 
contenttypeinfos = CreateSimpleType(factory, attributes, contenttypeinfos) 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

601 

814  602 
simpleContent["elements"] = [{"name": "content", "type": ELEMENT, 
603 
"elmt_type": contenttypeinfos, "doc": annotations, 

604 
"minOccurs": 1, "maxOccurs": 1}] 

605 
simpleContent["type"] = "simpleContent" 

606 
return simpleContent 

607 

608 

609 
def ReduceComplexContent(factory, attributes, elements): 

610 
annotations, children = factory.ReduceElements(elements) 

611 
complexContent = children[0].copy() 

612 
complexContent["type"] = "complexContent" 

613 
return complexContent 

614 

615 

616 
def ReduceComplexType(factory, attributes, elements): 

617 
annotations, children = factory.ReduceElements(elements) 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

618 

814  619 
if len(children) > 0: 
620 
if children[0]["type"] in ["simpleContent", "complexContent"]: 

621 
complexType = children[0].copy() 

622 
complexType.update(attributes) 

623 
complexType["type"] = COMPLEXTYPE 

624 
return complexType 

625 
elif children[0]["type"] in ["group", "all", CHOICE, "sequence"]: 

626 
complexType = {"type": COMPLEXTYPE, "elements": [], "order": True, "doc": annotations} 

627 
complexType.update(attributes) 

628 
group = children.pop(0) 

629 
if group["type"] in ["all", "sequence"]: 

630 
choice_number = 0 

631 
for element in group["elements"]: 

632 
if element["type"] == CHOICE: 

633 
choice_number += 1 

634 
if (group["minOccurs"] == 0 or group["maxOccurs"] != 1) and len(group["elements"]) > 1 or choice_number > 1: 

635 
content = {"type": CHOICE, "name": "content", "choices": [group], "minOccurs": 1, "maxOccurs": 1} 

636 
complexType["elements"].append(content) 

637 
else: 

638 
if len(group["elements"]) == 1: 

639 
if group["minOccurs"] == 0: 

640 
group["elements"][0]["minOccurs"] = group["minOccurs"] 

641 
if group["maxOccurs"] != 1: 

642 
group["elements"][0]["maxOccurs"] = group["maxOccurs"] 

643 
for element in group["elements"]: 

644 
if element["type"] == CHOICE: 

645 
element["name"] = "content" 

646 
complexType["elements"] = group["elements"] 

647 
complexType["order"] = group["order"] 

648 
elif group["type"] == CHOICE: 

649 
content = group.copy() 

650 
content["name"] = "content" 

651 
complexType["elements"].append(content) 

652 
elif group["type"] == "group": 

653 
elmtgroup = factory.FindSchemaElement(child["ref"], ELEMENTSGROUP) 

1763
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

654 
if "elements" in elmtgroup: 
814  655 
complexType["elements"] = elmtgroup["elements"] 
656 
complexType["order"] = elmtgroup["order"] 

657 
else: 

658 
content = elmtgroup.copy() 

659 
content["name"] = "content" 

660 
complexType["elements"].append(content) 

661 
else: 

662 
complexType = {"elements": [], "order": True, "doc": annotations} 

663 
complexType.update(attributes) 

664 
complexType["type"] = COMPLEXTYPE 

665 
complexType["attributes"] = ExtractAttributes(factory, children) 

666 
return complexType 

667 
else: 

668 
raise ValueError("\"ComplexType\" can't be empty!") 

669 

670 

671 
# Attribute elements 

672 

673 
def ReduceAnyAttribute(factory, attributes, elements): 

1739
ec153828ded2
cleanup: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1736
diff
changeset

674 
return {"type": "anyAttribute"} 
814  675 

676 

677 
def ReduceAttribute(factory, attributes, elements): 

678 
annotations, children = factory.ReduceElements(elements) 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

679 

1763
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

680 
if "default" in attributes: 
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

681 
if "fixed" in attributes: 
814  682 
raise ValueError("\"default\" and \"fixed\" can't be defined at the same time!") 
683 
elif attributes.get("use", "optional") != "optional": 

684 
raise ValueError("if \"default\" present, \"use\" can only have the value \"optional\"!") 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

685 

814  686 
attribute = {"type": ATTRIBUTE, "attr_type": attributes.get("type", None), "doc": annotations} 
687 
if len(children) > 0: 

688 
if attribute["attr_type"] is None: 

689 
attribute["attr_type"] = children[0] 

690 
else: 

691 
raise ValueError("Only one type can be defined for attribute!") 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

692 

1763
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

693 
if "ref" in attributes: 
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

694 
if "name" in attributes: 
814  695 
raise ValueError("\"ref\" and \"name\" can't be defined at the same time!") 
1763
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

696 
elif "form" in attributes: 
814  697 
raise ValueError("\"ref\" and \"form\" can't be defined at the same time!") 
698 
elif attribute["attr_type"] is not None: 

699 
raise ValueError("if \"ref\" is present, no type can be defined!") 

700 
elif attribute["attr_type"] is None: 

701 
raise ValueError("No type has been defined for attribute \"%s\"!" % attributes["name"]) 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

702 

1763
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

703 
if "type" in attributes: 
814  704 
tmp_attrs = attributes.copy() 
705 
tmp_attrs.pop("type") 

706 
attribute.update(tmp_attrs) 

707 
else: 

708 
attribute.update(attributes) 

709 
return attribute 

710 

711 

712 
def ReduceAttributeGroup(factory, attributes, elements): 

713 
annotations, children = factory.ReduceElements(elements) 

1763
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

714 
if "ref" in attributes: 
814  715 
return {"type": "attributeGroup", "ref": attributes["ref"], "doc": annotations} 
716 
else: 

717 
return {"type": ATTRIBUTESGROUP, "attributes": ExtractAttributes(factory, children), "doc": annotations} 

718 

719 

720 
# Elements groups 

721 

722 
def ReduceAny(factory, attributes, elements): 

723 
annotations, children = factory.ReduceElements(elements) 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

724 

814  725 
any = {"type": ANY, "doc": annotations} 
726 
any.update(attributes) 

727 
return any 

728 

1736
7e61baa047f0
cleanup: fix PEP8 E302 expected 2 blank lines, found 1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1734
diff
changeset

729 

814  730 
def ReduceElement(factory, attributes, elements): 
731 
annotations, children = factory.ReduceElements(elements) 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

732 

814  733 
types = [] 
734 
constraints = [] 

735 
for child in children: 

736 
if child["type"] == CONSTRAINT: 

737 
constraints.append(child) 

738 
else: 

739 
types.append(child) 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

740 

1763
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

741 
if "default" in attributes and "fixed" in attributes: 
814  742 
raise ValueError("\"default\" and \"fixed\" can't be defined at the same time!") 
1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

743 

1763
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

744 
if "ref" in attributes: 
814  745 
for attr in ["name", "default", "fixed", "form", "block", "type"]: 
1763
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

746 
if attr in attributes: 
814  747 
raise ValueError("\"ref\" and \"%s\" can't be defined at the same time!" % attr) 
1763
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

748 
if "nillable" in attributes: 
814  749 
raise ValueError("\"ref\" and \"nillable\" can't be defined at the same time!") 
750 
if len(types) > 0: 

751 
raise ValueError("No type and no constraints can be defined where \"ref\" is defined!") 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

752 

814  753 
infos = factory.FindSchemaElement(attributes["ref"], ELEMENT) 
754 
if infos is not None: 

755 
element = infos.copy() 

756 
element["constraints"] = constraints 

757 
element["minOccurs"] = attributes["minOccurs"] 

758 
element["maxOccurs"] = attributes["maxOccurs"] 

759 
return element 

760 
else: 

761 
raise ValueError("\"%s\" base type isn't defined or circular referenced!" % name) 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

762 

1763
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

763 
elif "name" in attributes: 
814  764 
element = {"type": ELEMENT, "elmt_type": attributes.get("type", None), "constraints": constraints, "doc": annotations} 
765 
if len(types) > 0: 

766 
if element["elmt_type"] is None: 

767 
element["elmt_type"] = types[0] 

768 
else: 

769 
raise ValueError("Only one type can be defined for attribute!") 

770 
elif element["elmt_type"] is None: 

771 
element["elmt_type"] = "tag" 

772 
element["type"] = TAG 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

773 

1763
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

774 
if "type" in attributes: 
814  775 
tmp_attrs = attributes.copy() 
776 
tmp_attrs.pop("type") 

777 
element.update(tmp_attrs) 

778 
else: 

779 
element.update(attributes) 

780 
return element 

781 
else: 

782 
raise ValueError("\"Element\" must have at least a \"ref\" or a \"name\" defined!") 

783 

1736
7e61baa047f0
cleanup: fix PEP8 E302 expected 2 blank lines, found 1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1734
diff
changeset

784 

814  785 
def ReduceAll(factory, attributes, elements): 
786 
annotations, children = factory.ReduceElements(elements) 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

787 

814  788 
for child in children: 
789 
if children["maxOccurs"] == "unbounded" or children["maxOccurs"] > 1: 

790 
raise ValueError("\"all\" item can't have \"maxOccurs\" attribute greater than 1!") 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

791 

814  792 
return {"type": "all", "elements": children, "minOccurs": attributes["minOccurs"], 
793 
"maxOccurs": attributes["maxOccurs"], "order": False, "doc": annotations} 

794 

795 

796 
def ReduceChoice(factory, attributes, elements): 

797 
annotations, children = factory.ReduceElements(elements) 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

798 

814  799 
choices = [] 
800 
for child in children: 

801 
if child["type"] in [ELEMENT, ANY, TAG]: 

802 
choices.append(child) 

803 
elif child["type"] == "sequence": 

804 
child["minOccurs"] = child["maxOccurs"] = 1 

805 
choices.append(child) 

1782
5b6ad7a7fd9d
cleanup: fix PEP8 E265 block comment should start with '# '
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1780
diff
changeset

806 
# raise ValueError("\"sequence\" in \"choice\" is not supported. Create instead a new complex type!") 
814  807 
elif child["type"] == CHOICE: 
808 
choices.extend(child["choices"]) 

809 
elif child["type"] == "group": 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

810 
elmtgroup = factory.FindSchemaElement(child["ref"], ELEMENTSGROUP) 
1775
b45f2768fab1
cleanup: fix PEP8 E713 test for membership should be 'not in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1774
diff
changeset

811 
if "choices" not in elmtgroup: 
814  812 
raise ValueError("Only group composed of \"choice\" can be referenced in \"choice\" element!") 
813 
choices_tmp = [] 

814 
for choice in elmtgroup["choices"]: 

815 
if not isinstance(choice["elmt_type"], (UnicodeType, StringType)) and choice["elmt_type"]["type"] == COMPLEXTYPE: 

816 
elmt_type = "%s_%s" % (elmtgroup["name"], choice["name"]) 

817 
if factory.TargetNamespace is not None: 

818 
elmt_type = "%s:%s" % (factory.TargetNamespace, elmt_type) 

819 
new_choice = choice.copy() 

820 
new_choice["elmt_type"] = elmt_type 

821 
choices_tmp.append(new_choice) 

822 
else: 

823 
choices_tmp.append(choice) 

824 
choices.extend(choices_tmp) 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

825 

814  826 
for choice in choices: 
827 
attributes["minOccurs"] = min(attributes["minOccurs"], choice["minOccurs"]) 

828 
choice["minOccurs"] = 1 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

829 

814  830 
return {"type": CHOICE, "choices": choices, "minOccurs": attributes["minOccurs"], 
831 
"maxOccurs": attributes["maxOccurs"], "doc": annotations} 

832 

833 

834 
def ReduceSequence(factory, attributes, elements): 

835 
annotations, children = factory.ReduceElements(elements) 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

836 

814  837 
sequence = [] 
838 
for child in children: 

839 
if child["type"] in [ELEMENT, ANY, TAG, CHOICE]: 

840 
sequence.append(child) 

841 
elif child["type"] == "sequence": 

842 
sequence.extend(child["elements"]) 

843 
elif child["type"] == "group": 

844 
elmtgroup = factory.FindSchemaElement(child["ref"], ELEMENTSGROUP) 

1775
b45f2768fab1
cleanup: fix PEP8 E713 test for membership should be 'not in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1774
diff
changeset

845 
if "elements" not in elmtgroup or not elmtgroup["order"]: 
814  846 
raise ValueError("Only group composed of \"sequence\" can be referenced in \"sequence\" element!") 
847 
elements_tmp = [] 

848 
for element in elmtgroup["elements"]: 

849 
if not isinstance(element["elmt_type"], (UnicodeType, StringType)) and element["elmt_type"]["type"] == COMPLEXTYPE: 

1734
750eeb7230a1
cleanup: fix some PEP8 E228 missing whitespace around modulo operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1732
diff
changeset

850 
elmt_type = "%s_%s" % (elmtgroup["name"], element["name"]) 
814  851 
if factory.TargetNamespace is not None: 
852 
elmt_type = "%s:%s" % (factory.TargetNamespace, elmt_type) 

853 
new_element = element.copy() 

854 
new_element["elmt_type"] = elmt_type 

855 
elements_tmp.append(new_element) 

856 
else: 

857 
elements_tmp.append(element) 

858 
sequence.extend(elements_tmp) 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

859 

814  860 
return {"type": "sequence", "elements": sequence, "minOccurs": attributes["minOccurs"], 
861 
"maxOccurs": attributes["maxOccurs"], "order": True, "doc": annotations} 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

862 

64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

863 

814  864 
def ReduceGroup(factory, attributes, elements): 
865 
annotations, children = factory.ReduceElements(elements) 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

866 

1763
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

867 
if "ref" in attributes: 
814  868 
return {"type": "group", "ref": attributes["ref"], "doc": annotations} 
869 
else: 

870 
element = children[0] 

871 
group = {"type": ELEMENTSGROUP, "doc": annotations} 

872 
if element["type"] == CHOICE: 

873 
group["choices"] = element["choices"] 

874 
else: 

1683
57b4ac796dcb
fix reducing groups with ordered elements
Surkov Sergey <surkovsv93@gmail.com>
parents:
1571
diff
changeset

875 
group.update({"elements": element["elements"], "order": element["order"]}) 
814  876 
group.update(attributes) 
877 
return group 

878 

879 
# Constraint elements 

880 

1736
7e61baa047f0
cleanup: fix PEP8 E302 expected 2 blank lines, found 1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1734
diff
changeset

881 

814  882 
def ReduceUnique(factory, attributes, elements): 
883 
annotations, children = factory.ReduceElements(elements) 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

884 

814  885 
unique = {"type": CONSTRAINT, "const_type": "unique", "selector": children[0], "fields": children[1:]} 
886 
unique.update(attributes) 

887 
return unique 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

888 

1736
7e61baa047f0
cleanup: fix PEP8 E302 expected 2 blank lines, found 1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1734
diff
changeset

889 

814  890 
def ReduceKey(factory, attributes, elements): 
891 
annotations, children = factory.ReduceElements(elements) 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

892 

814  893 
key = {"type": CONSTRAINT, "const_type": "key", "selector": children[0], "fields": children[1:]} 
894 
key.update(attributes) 

895 
return key 

896 

1736
7e61baa047f0
cleanup: fix PEP8 E302 expected 2 blank lines, found 1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1734
diff
changeset

897 

814  898 
def ReduceKeyRef(factory, attributes, elements): 
899 
annotations, children = factory.ReduceElements(elements) 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

900 

814  901 
keyref = {"type": CONSTRAINT, "const_type": "keyref", "selector": children[0], "fields": children[1:]} 
902 
keyref.update(attributes) 

903 
return keyref 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

904 

1736
7e61baa047f0
cleanup: fix PEP8 E302 expected 2 blank lines, found 1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1734
diff
changeset

905 

814  906 
def ReduceSelector(factory, attributes, elements): 
907 
annotations, children = factory.ReduceElements(elements) 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

908 

814  909 
selector = {"type": CONSTRAINT, "const_type": "selector"} 
910 
selector.update(attributes) 

911 
return selector 

912 

1736
7e61baa047f0
cleanup: fix PEP8 E302 expected 2 blank lines, found 1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1734
diff
changeset

913 

814  914 
def ReduceField(factory, attributes, elements): 
915 
annotations, children = factory.ReduceElements(elements) 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

916 

814  917 
field = {"type": CONSTRAINT, "const_type": "field"} 
918 
field.update(attributes) 

919 
return field 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

920 

814  921 

922 
# Inclusion elements 

923 

924 
def ReduceImport(factory, attributes, elements): 

925 
annotations, children = factory.ReduceElements(elements) 

926 
raise ValueError("\"import\" element isn't supported yet!") 

927 

1736
7e61baa047f0
cleanup: fix PEP8 E302 expected 2 blank lines, found 1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1734
diff
changeset

928 

814  929 
def ReduceInclude(factory, attributes, elements): 
930 
annotations, children = factory.ReduceElements(elements) 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

931 

814  932 
if factory.FileName is None: 
933 
raise ValueError("Include in XSD string not yet supported") 

934 
filepath = attributes["schemaLocation"] 

935 
if filepath is not None and not os.path.exists(filepath): 

936 
filepath = os.path.join(factory.BaseFolder, filepath) 

937 
if not os.path.exists(filepath): 

938 
raise ValueError("No file '%s' found for include" % attributes["schemaLocation"]) 

939 
xsdfile = open(filepath, 'r') 

940 
include_factory = XSDClassFactory(minidom.parse(xsdfile), filepath) 

941 
xsdfile.close() 

942 
include_factory.CreateClasses() 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

943 

814  944 
if factory.TargetNamespace == include_factory.TargetNamespace: 
945 
factory.Namespaces[factory.TargetNamespace].update(include_factory.Namespaces[include_factory.TargetNamespace]) 

946 
else: 

947 
factory.Namespaces[include_factory.TargetNamespace] = include_factory.Namespaces[include_factory.TargetNamespace] 

948 
factory.ComputedClasses.update(include_factory.ComputedClasses) 

1322
0a9227f743b3
Fixed xmlclass for working with included files, adding support for SimpleType elements and solving ambiguity in extension class when different elements share the same name and parent name
Laurent Bessard
parents:
1315
diff
changeset

949 
factory.ComputedClassesLookUp.update(include_factory.ComputedClassesLookUp) 
0a9227f743b3
Fixed xmlclass for working with included files, adding support for SimpleType elements and solving ambiguity in extension class when different elements share the same name and parent name
Laurent Bessard
parents:
1315
diff
changeset

950 
factory.EquivalentClassesParent.update(include_factory.EquivalentClassesParent) 
814  951 
return None 
1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

952 

1736
7e61baa047f0
cleanup: fix PEP8 E302 expected 2 blank lines, found 1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1734
diff
changeset

953 

814  954 
def ReduceRedefine(factory, attributes, elements): 
955 
annotations, children = factory.ReduceElements(elements) 

956 
raise ValueError("\"redefine\" element isn't supported yet!") 

957 

958 

959 
# Schema element 

960 

961 
def ReduceSchema(factory, attributes, elements): 

962 
factory.AttributeFormDefault = attributes["attributeFormDefault"] 

963 
factory.ElementFormDefault = attributes["elementFormDefault"] 

964 
factory.BlockDefault = attributes["blockDefault"] 

965 
factory.FinalDefault = attributes["finalDefault"] 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

966 

1315
ff14a66bbd12
Fixed Beremiz for working with new xmlclass support using lxml
Laurent Bessard
parents:
1290
diff
changeset

967 
targetNamespace = attributes.get("targetNamespace", None) 
ff14a66bbd12
Fixed Beremiz for working with new xmlclass support using lxml
Laurent Bessard
parents:
1290
diff
changeset

968 
factory.TargetNamespace = factory.DefinedNamespaces.get(targetNamespace, None) 
1290
13ee5f4ab612
First stage of xmlclass refactoring using lxml
Laurent Bessard
parents:
1078
diff
changeset

969 
if factory.TargetNamespace is not None: 
1315
ff14a66bbd12
Fixed Beremiz for working with new xmlclass support using lxml
Laurent Bessard
parents:
1290
diff
changeset

970 
factory.etreeNamespaceFormat = "{%s}%%s" % targetNamespace 
814  971 
factory.Namespaces[factory.TargetNamespace] = {} 
1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

972 

814  973 
annotations, children = factory.ReduceElements(elements, True) 
1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

974 

814  975 
for child in children: 
1763
bcc07ff2362c
cleanup: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1762
diff
changeset

976 
if "name" in child: 
814  977 
infos = factory.GetQualifiedNameInfos(child["name"], factory.TargetNamespace, True) 
978 
if infos is None: 

979 
factory.Namespaces[factory.TargetNamespace][child["name"]] = child 

980 
elif not CompareSchema(infos, child): 

981 
raise ValueError("\"%s\" is defined twice in targetNamespace!" % child["name"]) 

982 

1736
7e61baa047f0
cleanup: fix PEP8 E302 expected 2 blank lines, found 1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1734
diff
changeset

983 

814  984 
def CompareSchema(schema, reference): 
985 
if isinstance(schema, ListType): 

986 
if not isinstance(reference, ListType) or len(schema) != len(reference): 

987 
return False 

988 
for i, value in enumerate(schema): 

989 
result = CompareSchema(value, reference[i]) 

990 
if not result: 

991 
return result 

992 
return True 

993 
elif isinstance(schema, DictType): 

994 
if not isinstance(reference, DictType) or len(schema) != len(reference): 

995 
return False 

996 
for name, value in schema.items(): 

997 
ref_value = reference.get(name, None) 

1743
c3c3d1318130
cleanup: fix PEP8 E711 comparison to None should be 'if cond is not None:'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1740
diff
changeset

998 
if ref_value is None and value is not None: 
814  999 
return False 
1000 
result = CompareSchema(value, ref_value) 

1001 
if not result: 

1002 
return result 

1003 
return True 

1004 
elif isinstance(schema, FunctionType): 

1005 
if not isinstance(reference, FunctionType) or schema.__name__ != reference.__name__: 

1006 
return False 

1007 
else: 

1008 
return True 

1009 
return schema == reference 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

1010 

1782
5b6ad7a7fd9d
cleanup: fix PEP8 E265 block comment should start with '# '
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1780
diff
changeset

1011 

5b6ad7a7fd9d
cleanup: fix PEP8 E265 block comment should start with '# '
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1780
diff
changeset

1012 
#  
814  1013 
# Base class for XSD schema extraction 
1782
5b6ad7a7fd9d
cleanup: fix PEP8 E265 block comment should start with '# '
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1780
diff
changeset

1014 
#  
814  1015 

1016 

1017 
class XSDClassFactory(ClassFactory): 

1018 

1019 
def __init__(self, document, filepath=None, debug=False): 

1020 
ClassFactory.__init__(self, document, filepath, debug) 

1021 
self.Namespaces["xml"] = { 

1022 
"lang": { 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

1023 
"type": SYNTAXATTRIBUTE, 
814  1024 
"extract": { 
1025 
"default": GenerateModelNameExtraction("lang", LANGUAGE_model) 

1026 
} 

1027 
} 

1028 
} 

1029 
self.Namespaces["xsi"] = { 

1030 
"noNamespaceSchemaLocation": { 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

1031 
"type": SYNTAXATTRIBUTE, 
814  1032 
"extract": { 
1033 
"default": NotSupportedYet("noNamespaceSchemaLocation") 

1034 
} 

1035 
}, 

1036 
"nil": { 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

1037 
"type": SYNTAXATTRIBUTE, 
814  1038 
"extract": { 
1039 
"default": NotSupportedYet("nil") 

1040 
} 

1041 
}, 

1042 
"schemaLocation": { 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

1043 
"type": SYNTAXATTRIBUTE, 
814  1044 
"extract": { 
1045 
"default": NotSupportedYet("schemaLocation") 

1046 
} 

1047 
}, 

1048 
"type": { 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

1049 
"type": SYNTAXATTRIBUTE, 
814  1050 
"extract": { 
1051 
"default": NotSupportedYet("type") 

1052 
} 

1053 
} 

1054 
} 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

1055 

814  1056 
def ParseSchema(self): 
1057 
for child in self.Document.childNodes: 

1058 
if child.nodeType == self.Document.ELEMENT_NODE: 

1059 
schema = child 

1060 
break 

1061 
for qualified_name, attr in schema._attrs.items(): 

1290
13ee5f4ab612
First stage of xmlclass refactoring using lxml
Laurent Bessard
parents:
1078
diff
changeset

1062 
namespace, name = DecomposeQualifiedName(qualified_name) 
13ee5f4ab612
First stage of xmlclass refactoring using lxml
Laurent Bessard
parents:
1078
diff
changeset

1063 
if namespace == "xmlns": 
13ee5f4ab612
First stage of xmlclass refactoring using lxml
Laurent Bessard
parents:
1078
diff
changeset

1064 
value = GetAttributeValue(attr) 
13ee5f4ab612
First stage of xmlclass refactoring using lxml
Laurent Bessard
parents:
1078
diff
changeset

1065 
self.DefinedNamespaces[value] = name 
13ee5f4ab612
First stage of xmlclass refactoring using lxml
Laurent Bessard
parents:
1078
diff
changeset

1066 
self.NSMAP[name] = value 
13ee5f4ab612
First stage of xmlclass refactoring using lxml
Laurent Bessard
parents:
1078
diff
changeset

1067 
if value == "http://www.w3.org/2001/XMLSchema": 
814  1068 
self.SchemaNamespace = name 
1290
13ee5f4ab612
First stage of xmlclass refactoring using lxml
Laurent Bessard
parents:
1078
diff
changeset

1069 
self.Namespaces[self.SchemaNamespace] = XSD_NAMESPACE 
814  1070 
self.Schema = XSD_NAMESPACE["schema"]["extract"]["default"](self, schema) 
1071 
ReduceSchema(self, self.Schema[1], self.Schema[2]) 

1072 

1073 
def FindSchemaElement(self, element_name, element_type=None): 

1074 
namespace, name = DecomposeQualifiedName(element_name) 

1075 
element = self.GetQualifiedNameInfos(name, namespace, True) 

1076 
if element is None and namespace == self.TargetNamespace and name not in self.CurrentCompilations: 

1077 
self.CurrentCompilations.append(name) 

1078 
element = self.CreateSchemaElement(name, element_type) 

1079 
self.CurrentCompilations.pop(1) 

1080 
if element is not None: 

1081 
self.Namespaces[self.TargetNamespace][name] = element 

1082 
if element is None: 

1083 
if name in self.CurrentCompilations: 

1084 
if self.Debug: 

1085 
print "Warning : \"%s\" is circular referenced!" % element_name 

1086 
else: 

1087 
raise ValueError("\"%s\" isn't defined!" % element_name) 

1088 
if element_type is not None and element["type"] != element_type: 

1089 
raise ValueError("\"%s\" isn't of the expected type!" % element_name) 

1090 
return element 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

1091 

814  1092 
def CreateSchemaElement(self, element_name, element_type): 
1093 
for type, attributes, elements in self.Schema[2]: 

1094 
namespace, name = DecomposeQualifiedName(type) 

1095 
if attributes.get("name", None) == element_name: 

1096 
element_infos = None 

1097 
if element_type in (ATTRIBUTE, None) and name == "attribute": 

1098 
element_infos = ReduceAttribute(self, attributes, elements) 

1099 
elif element_type in (ELEMENT, None) and name == "element": 

1100 
element_infos = ReduceElement(self, attributes, elements) 

1101 
elif element_type in (ATTRIBUTESGROUP, None) and name == "attributeGroup": 

1102 
element_infos = ReduceAttributeGroup(self, attributes, elements) 

1103 
elif element_type in (ELEMENTSGROUP, None) and name == "group": 

1104 
element_infos = ReduceGroup(self, attributes, elements) 

1105 
elif element_type in (SIMPLETYPE, None) and name == "simpleType": 

1106 
element_infos = ReduceSimpleType(self, attributes, elements) 

1107 
elif element_type in (COMPLEXTYPE, None) and name == "complexType": 

1108 
element_infos = ReduceComplexType(self, attributes, elements) 

1109 
if element_infos is not None: 

1110 
self.Namespaces[self.TargetNamespace][element_name] = element_infos 

1111 
return element_infos 

1112 
return None 

1113 

1736
7e61baa047f0
cleanup: fix PEP8 E302 expected 2 blank lines, found 1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1734
diff
changeset

1114 

1290
13ee5f4ab612
First stage of xmlclass refactoring using lxml
Laurent Bessard
parents:
1078
diff
changeset

1115 
def GenerateParserFromXSD(filepath): 
1736
7e61baa047f0
cleanup: fix PEP8 E302 expected 2 blank lines, found 1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1734
diff
changeset

1116 
""" 
7e61baa047f0
cleanup: fix PEP8 E302 expected 2 blank lines, found 1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1734
diff
changeset

1117 
This function opens the xsd file and generate a xml parser with class lookup from 
7e61baa047f0
cleanup: fix PEP8 E302 expected 2 blank lines, found 1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1734
diff
changeset

1118 
the xml tree 
7e61baa047f0
cleanup: fix PEP8 E302 expected 2 blank lines, found 1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1734
diff
changeset

1119 
""" 
814  1120 
xsdfile = open(filepath, 'r') 
1290
13ee5f4ab612
First stage of xmlclass refactoring using lxml
Laurent Bessard
parents:
1078
diff
changeset

1121 
xsdstring = xsdfile.read() 
814  1122 
xsdfile.close() 
1322
0a9227f743b3
Fixed xmlclass for working with included files, adding support for SimpleType elements and solving ambiguity in extension class when different elements share the same name and parent name
Laurent Bessard
parents:
1315
diff
changeset

1123 
cwd = os.getcwd() 
0a9227f743b3
Fixed xmlclass for working with included files, adding support for SimpleType elements and solving ambiguity in extension class when different elements share the same name and parent name
Laurent Bessard
parents:
1315
diff
changeset

1124 
os.chdir(os.path.dirname(filepath)) 
0a9227f743b3
Fixed xmlclass for working with included files, adding support for SimpleType elements and solving ambiguity in extension class when different elements share the same name and parent name
Laurent Bessard
parents:
1315
diff
changeset

1125 
parser = GenerateParser(XSDClassFactory(minidom.parseString(xsdstring), filepath), xsdstring) 
0a9227f743b3
Fixed xmlclass for working with included files, adding support for SimpleType elements and solving ambiguity in extension class when different elements share the same name and parent name
Laurent Bessard
parents:
1315
diff
changeset

1126 
os.chdir(cwd) 
0a9227f743b3
Fixed xmlclass for working with included files, adding support for SimpleType elements and solving ambiguity in extension class when different elements share the same name and parent name
Laurent Bessard
parents:
1315
diff
changeset

1127 
return parser 
814  1128 

1736
7e61baa047f0
cleanup: fix PEP8 E302 expected 2 blank lines, found 1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1734
diff
changeset

1129 

1290
13ee5f4ab612
First stage of xmlclass refactoring using lxml
Laurent Bessard
parents:
1078
diff
changeset

1130 
def GenerateParserFromXSDstring(xsdstring): 
1736
7e61baa047f0
cleanup: fix PEP8 E302 expected 2 blank lines, found 1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1734
diff
changeset

1131 
""" 
7e61baa047f0
cleanup: fix PEP8 E302 expected 2 blank lines, found 1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1734
diff
changeset

1132 
This function generate a xml from the xsd given as a string 
7e61baa047f0
cleanup: fix PEP8 E302 expected 2 blank lines, found 1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1734
diff
changeset

1133 
""" 
1315
ff14a66bbd12
Fixed Beremiz for working with new xmlclass support using lxml
Laurent Bessard
parents:
1290
diff
changeset

1134 
return GenerateParser(XSDClassFactory(minidom.parseString(xsdstring)), xsdstring) 
814  1135 

1136 

1782
5b6ad7a7fd9d
cleanup: fix PEP8 E265 block comment should start with '# '
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1780
diff
changeset

1137 
#  
814  1138 
# XSD schema syntax elements 
1782
5b6ad7a7fd9d
cleanup: fix PEP8 E265 block comment should start with '# '
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1780
diff
changeset

1139 
#  
5b6ad7a7fd9d
cleanup: fix PEP8 E265 block comment should start with '# '
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1780
diff
changeset

1140 

814  1141 

1142 
XSD_NAMESPACE = { 

1143 

1782
5b6ad7a7fd9d
cleanup: fix PEP8 E265 block comment should start with '# '
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1780
diff
changeset

1144 
#  
1776
81aa8aaccdd4
cleanup: fix PEP8 E122 continuation line missing indentation or outdented
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1775
diff
changeset

1145 
# Syntax elements definition 
1782
5b6ad7a7fd9d
cleanup: fix PEP8 E265 block comment should start with '# '
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1780
diff
changeset

1146 
#  
814  1147 

1768
691083b5682a
cleanup: fix PEP8 E128 continuation line underindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset

1148 
"all": { 
691083b5682a
cleanup: fix PEP8 E128 continuation line underindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset

1149 
"struct": """ 
814  1150 
<all 
1151 
id = ID 

1152 
maxOccurs = 1 : 1 

1153 
minOccurs = (0  1) : 1 

1154 
{any attributes with nonschema namespace . . .}> 

1155 
Content: (annotation?, element*) 

1156 
</all>""", 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

1157 
"type": SYNTAXELEMENT, 
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

1158 
"extract": { 
1768
691083b5682a
cleanup: fix PEP8 E128 continuation line underindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset

1159 
"default": GenerateElement( 
691083b5682a
cleanup: fix PEP8 E128 continuation line underindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset

1160 
"all", ["id", "maxOccurs", "minOccurs"], 
814  1161 
re.compile("((?:annotation )?(?:element )*)")) 
1162 
}, 

1163 
"reduce": ReduceAll 

1164 
}, 

1165 

1768
691083b5682a
cleanup: fix PEP8 E128 continuation line underindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset

1166 
"annotation": { 
691083b5682a
cleanup: fix PEP8 E128 continuation line underindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset

1167 
"struct": """ 
814  1168 
<annotation 
1169 
id = ID 

1170 
{any attributes with nonschema namespace . . .}> 

1171 
Content: (appinfo  documentation)* 

1172 
</annotation>""", 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

1173 
"type": SYNTAXELEMENT, 
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

1174 
"extract": { 
1768
691083b5682a
cleanup: fix PEP8 E128 continuation line underindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset

1175 
"default": GenerateElement( 
691083b5682a
cleanup: fix PEP8 E128 continuation line underindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset

1176 
"annotation", ["id"], 
814  1177 
re.compile("((?:app_info documentation )*)")) 
1178 
}, 

1179 
"reduce": ReduceAnnotation 

1180 
}, 

1181 

1768
691083b5682a
cleanup: fix PEP8 E128 continuation line underindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset

1182 
"any": { 
691083b5682a
cleanup: fix PEP8 E128 continuation line underindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset

1183 
"struct": """ 
814  1184 
<any 
1185 
id = ID 

1186 
maxOccurs = (nonNegativeInteger  unbounded) : 1 

1187 
minOccurs = nonNegativeInteger : 1 

1188 
namespace = ((##any  ##other)  List of (anyURI  (##targetNamespace  ##local)) ) : ##any 

1189 
processContents = (lax  skip  strict) : strict 

1190 
{any attributes with nonschema namespace . . .}> 

1191 
Content: (annotation?) 

1192 
</any>""", 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

1193 
"type": SYNTAXELEMENT, 
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

1194 
"extract": { 
1768
691083b5682a
cleanup: fix PEP8 E128 continuation line underindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset

1195 
"default": GenerateElement( 
691083b5682a
cleanup: fix PEP8 E128 continuation line underindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset

1196 
"any", 
1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

1197 
["id", "maxOccurs", "minOccurs", "namespace", "processContents"], 
814  1198 
re.compile("((?:annotation )?(?:simpleType )*)")) 
1199 
}, 

1200 
"reduce": ReduceAny 

1201 
}, 

1202 

1768
691083b5682a
cleanup: fix PEP8 E128 continuation line underindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset

1203 
"anyAttribute": { 
691083b5682a
cleanup: fix PEP8 E128 continuation line underindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset

1204 
"struct": """ 
814  1205 
<anyAttribute 
1206 
id = ID 

1207 
namespace = ((##any  ##other)  List of (anyURI  (##targetNamespace  ##local)) ) : ##any 

1208 
processContents = (lax  skip  strict) : strict 

1209 
{any attributes with nonschema namespace . . .}> 

1210 
Content: (annotation?) 

1211 
</anyAttribute>""", 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

1212 
"type": SYNTAXELEMENT, 
814  1213 
"extract": { 
1768
691083b5682a
cleanup: fix PEP8 E128 continuation line underindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset

1214 
"default": GenerateElement( 
691083b5682a
cleanup: fix PEP8 E128 continuation line underindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset

1215 
"anyAttribute", ["id", "namespace", "processContents"], ONLY_ANNOTATION) 
814  1216 
}, 
1217 
"reduce": ReduceAnyAttribute 

1218 
}, 

1219 

1768
691083b5682a
cleanup: fix PEP8 E128 continuation line underindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset

1220 
"appinfo": { 
691083b5682a
cleanup: fix PEP8 E128 continuation line underindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset

1221 
"struct": """ 
814  1222 
<appinfo 
1223 
source = anyURI 

1224 
{any attributes with nonschema namespace . . .}> 

1225 
Content: ({any})* 

1226 
</appinfo>""", 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

1227 
"type": SYNTAXELEMENT, 
814  1228 
"extract": { 
1229 
"default": GenerateElement("appinfo", ["source"], re.compile("(.*)"), True) 

1230 
}, 

1231 
"reduce": ReduceAppInfo 

1232 
}, 

1233 

1768
691083b5682a
cleanup: fix PEP8 E128 continuation line underindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset

1234 
"attribute": { 
691083b5682a
cleanup: fix PEP8 E128 continuation line underindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset

1235 
"struct": """ 
814  1236 
<attribute 
1237 
default = string 

1238 
fixed = string 

1239 
form = (qualified  unqualified) 

1240 
id = ID 

1241 
name = NCName 

1242 
ref = QName 

1243 
type = QName 

1244 
use = (optional  prohibited  required) : optional 

1245 
{any attributes with nonschema namespace . . .}> 

1246 
Content: (annotation?, simpleType?) 

1247 
</attribute>""", 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

1248 
"type": SYNTAXELEMENT, 
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

1249 
"extract": { 
1768
691083b5682a
cleanup: fix PEP8 E128 continuation line underindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset

1250 
"default": GenerateElement( 
691083b5682a
cleanup: fix PEP8 E128 continuation line underindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset

1251 
"attribute", 
1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

1252 
["default", "fixed", "form", "id", "name", "ref", "type", "use"], 
814  1253 
re.compile("((?:annotation )?(?:simpleType )?)")), 
1768
691083b5682a
cleanup: fix PEP8 E128 continuation line underindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset

1254 
"schema": GenerateElement( 
691083b5682a
cleanup: fix PEP8 E128 continuation line underindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset

1255 
"attribute", 
1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

1256 
["default", "fixed", "form", "id", "name", "type"], 
814  1257 
re.compile("((?:annotation )?(?:simpleType )?)")) 
1258 
}, 

1259 
"reduce": ReduceAttribute 

1260 
}, 

1261 

1768
691083b5682a
cleanup: fix PEP8 E128 continuation line underindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset

1262 
"attributeGroup": { 
691083b5682a
cleanup: fix PEP8 E128 continuation line underindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset

1263 
"struct": """ 
814  1264 
<attributeGroup 
1265 
id = ID 

1266 
name = NCName 

1267 
ref = QName 

1268 
{any attributes with nonschema namespace . . .}> 

1269 
Content: (annotation?, ((attribute  attributeGroup)*, anyAttribute?)) 

1270 
</attributeGroup>""", 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

1271 
"type": SYNTAXELEMENT, 
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

1272 
"extract": { 
1768
691083b5682a
cleanup: fix PEP8 E128 continuation line underindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset

1273 
"default": GenerateElement( 
691083b5682a
cleanup: fix PEP8 E128 continuation line underindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset

1274 
"attributeGroup", 
814  1275 
["id", "ref"], ONLY_ANNOTATION), 
1768
691083b5682a
cleanup: fix PEP8 E128 continuation line underindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset

1276 
"schema": GenerateElement( 
691083b5682a
cleanup: fix PEP8 E128 continuation line underindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset

1277 
"attributeGroup", 
1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

1278 
["id", "name"], 
814  1279 
re.compile("((?:annotation )?(?:(?:attribute attributeGroup )*(?:anyAttribute )?))")) 
1280 
}, 

1281 
"reduce": ReduceAttributeGroup 

1282 
}, 

1283 

1768
691083b5682a
cleanup: fix PEP8 E128 continuation line underindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset

1284 
"choice": { 
691083b5682a
cleanup: fix PEP8 E128 continuation line underindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset

1285 
"struct": """ 
814  1286 
<choice 
1287 
id = ID 

1288 
maxOccurs = (nonNegativeInteger  unbounded) : 1 

1289 
minOccurs = nonNegativeInteger : 1 

1290 
{any attributes with nonschema namespace . . .}> 

1291 
Content: (annotation?, (element  group  choice  sequence  any)*) 

1292 
</choice>""", 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

1293 
"type": SYNTAXELEMENT, 
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

1294 
"extract": { 
1768
691083b5682a
cleanup: fix PEP8 E128 continuation line underindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset

1295 
"default": GenerateElement( 
691083b5682a
cleanup: fix PEP8 E128 continuation line underindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset

1296 
"choice", 
691083b5682a
cleanup: fix PEP8 E128 continuation line underindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset

1297 
["id", "maxOccurs", "minOccurs"], 
814  1298 
re.compile("((?:annotation )?(?:element group choice sequence any )*)")) 
1299 
}, 

1300 
"reduce": ReduceChoice 

1301 
}, 

1302 

1768
691083b5682a
cleanup: fix PEP8 E128 continuation line underindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset

1303 
"complexContent": { 
691083b5682a
cleanup: fix PEP8 E128 continuation line underindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset

1304 
"struct": """ 
814  1305 
<complexContent 
1306 
id = ID 

1307 
mixed = boolean 

1308 
{any attributes with nonschema namespace . . .}> 

1309 
Content: (annotation?, (restriction  extension)) 

1310 
</complexContent>""", 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

1311 
"type": SYNTAXELEMENT, 
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

1312 
"extract": { 
1768
691083b5682a
cleanup: fix PEP8 E128 continuation line underindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset

1313 
"default": GenerateElement( 
691083b5682a
cleanup: fix PEP8 E128 continuation line underindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset

1314 
"complexContent", 
691083b5682a
cleanup: fix PEP8 E128 continuation line underindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset

1315 
["id", "mixed"], 
814  1316 
re.compile("((?:annotation )?(?:restriction extension ))")) 
1317 
}, 

1318 
"reduce": ReduceComplexContent 

1319 
}, 

1320 

1768
691083b5682a
cleanup: fix PEP8 E128 continuation line underindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset

1321 
"complexType": { 
691083b5682a
cleanup: fix PEP8 E128 continuation line underindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset

1322 
"struct": """ 
814  1323 
<complexType 
1324 
abstract = boolean : false 

1325 
block = (#all  List of (extension  restriction)) 

1326 
final = (#all  List of (extension  restriction)) 

1327 
id = ID 

1328 
mixed = boolean : false 

1329 
name = NCName 

1330 
{any attributes with nonschema namespace . . .}> 

1331 
Content: (annotation?, (simpleContent  complexContent  ((group  all  choice  sequence)?, ((attribute  attributeGroup)*, anyAttribute?)))) 

1332 
</complexType>""", 

1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

1333 
"type": SYNTAXELEMENT, 
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

1334 
"extract": { 
1768
691083b5682a
cleanup: fix PEP8 E128 continuation line underindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset

1335 
"default": GenerateElement( 
691083b5682a
cleanup: fix PEP8 E128 continuation line underindented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset

1336 
"complexType", 
1730
64d8f52bc8c8
cleanup for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1683
diff
changeset

1337 
["abstract", "block", "final", "id", "mixed", "name"], 
814  1338 
re.compile("((?:annotation )?(?:simpleContent complexContent (?:(?:group all choice sequence )?(?:(?:attribute attributeGroup )*(?:anyAttribute )?))))")) 