diff --git a/README.md b/README.md index 1b10cf9..278a62d 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ +--- +WARN: It is just a prototype and currently just a subset of XSD capabilities. +--- + # YASD, Yet Another Schema Definition YASD is a YAML format for human writable XSDs (XML Schema Definition), humans @@ -36,7 +40,7 @@ To better understad what YASD does, see the inputs and outputs: ## Table of Contents -[TOC] +\[TOC\] ## Structure @@ -68,7 +72,8 @@ To better understad what YASD does, see the inputs and outputs: type: simple|empty|no_text|no_elements|mixed datatype: string|integer|decimal|date|time|language|duration|token|boolean|byte|int|double|float|long|short|normalizedString|dateTime|gDay|gMonth|gMonthDay|gYear|gYearMonth|negativeInteger|nonNegativeInteger|nonPositiveInteger|positiveInteger|unsignedLong|unsignedInt|unsignedShort|unsignedByte|anyURI|base64Binary|hexBinary|Name|QName|NCName|ID|IDREF|IDREFS|ENTITY|ENTITIES|NMTOKEN|NMTOKENS|NOTATION attributes: - - name: attribute_name + - ref: attribute_name + use: optional|required|prohibited - group: group_name ... children_order: all|choice|sequence @@ -77,6 +82,8 @@ To better understad what YASD does, see the inputs and outputs: maxOccurs: INTEGER|unbounded minOccurs: INTEGER - group_ref: group_name + maxOccurs: INTEGER|unbounded + minOccurs: INTEGER ... ### Attribute (ATTR) structure @@ -86,7 +93,6 @@ To better understad what YASD does, see the inputs and outputs: datatype: string|integer|decimal|date|time|language|duration|token|boolean|byte|int|double|float|long|short|normalizedString|dateTime|gDay|gMonth|gMonthDay|gYear|gYearMonth|negativeInteger|nonNegativeInteger|nonPositiveInteger|positiveInteger|unsignedLong|unsignedInt|unsignedShort|unsignedByte|anyURI|base64Binary|hexBinary|Name|QName|NCName|ID|IDREF|IDREFS|ENTITY|ENTITIES|NMTOKEN|NMTOKENS|NOTATION default: a_value fixed: a_value - use: required restriction: - CONSTRAIN ... @@ -188,7 +194,7 @@ Chart: | no_elements | ✗ | ✓ | ✓ | | mixed | ✓ | ✓ | ✓ | -> **Note 1**: read "elements" and "text" with "direct children…" as prefix. +> **Note 1**: read "elements" and "text" with "direct children..." as prefix. > **Note 2**: attributes are never mandatory; they could be zero or more. @@ -282,15 +288,20 @@ Only allowed for simple elements or attributes. Indicates that the attribute is required. -Optional. +Optional; if not present by default is `optional`. -Only `required` is valid as value. +Allowed uses: + +- `optional`. +- `required`. +- `prohibited`. ### `restriction` Indicates accepted constrained values for attribute. -Optional; if present, must contain at least one constrain. +Optional; if present, must contain at least one constrain and attribute +`datatype` is ignored. Allowed constrains: diff --git a/yasd.py b/yasd.py index e81bc4b..2e7ce97 100755 --- a/yasd.py +++ b/yasd.py @@ -142,6 +142,7 @@ class YASD: """ if type(outdata) is not str: outdata = outdata.prettify(formatter=self.formatter) + outdata = f'\n{outdata}' if self.stdout: if self.outfile is None: print(outdata) @@ -219,6 +220,7 @@ class YASDXSD: ... else: element = self.xsd.new_tag("group", nsprefix="xs") + element["name"] = el["name"] indicator = self.__build_indicator(el) element.append(indicator) self.xsd.schema.append(element) @@ -233,6 +235,8 @@ class YASDXSD: element = self.xsd.new_tag(tag, nsprefix="xs") if "default" in el.keys() and "fixed" in el.keys(): del el["fixed"] + if "restriction" in el.keys() and "datatype" in el.keys(): + del el["datatype"] for key, val in el.items(): if key == "datatype": element["type"] = f"xs:{val}" @@ -250,10 +254,13 @@ class YASDXSD: """ element = self.__build_complex_root(el) complex_type = self.__build_complex_type(el) - self.__add_references(complex_type, el, is_attr=True) if "children" in el.keys(): - indicator = self.__build_indicator(el) - complex_type.append(indicator) + if "group" in el["children"][0].keys(): + self.__add_references(complex_type, el) + self.__add_occurs(complex_type.group, el) + else: + complex_type.append(self.__build_indicator(el)) + self.__add_references(complex_type, el, is_attr=True) element.append(complex_type) self.xsd.schema.append(element) @@ -378,14 +385,25 @@ class YASDXSD: if key in el.keys(): for element in el[key]: node = self.xsd.new_tag(tag, nsprefix="xs") + self.__add_occurs(node, element) node["ref"] = element[name] - if "maxOccurs" in element.keys(): - node["maxOccurs"] = element["maxOccurs"] - if "minOccurs" in element.keys(): - node["minOccurs"] = element["minOccurs"] + if "use" in element.keys(): + node["use"] = element["use"] root.append(node) del el[key] + def __add_occurs(self, node, el): + """ + Adds occurrences to node. + + :param bs4.element.Tag node: node that requires occurrences + :param dict el: element that indicates if there are occurrences + """ + if "minOccurs" in el.keys(): + node["minOccurs"] = el["minOccurs"] + if "maxOccurs" in el.keys(): + node["maxOccurs"] = el["maxOccurs"] + def __sanitize(self, el): """ Prepares element or attribute for conversion.