示例#1
0
def insert_element_built_in_type(xsd_string, xpath, element_type_name):
    """Insert element with a builtin type in xsd string.

    Args:
        xsd_string: xsd string
        xpath: xpath where to insert the element
        element_type_name: name of the type to insert

    Returns:

    """
    # build the dom tree of the schema being built
    xsd_tree = XSDTree.build_tree(xsd_string)
    # get namespaces information for the schema
    namespaces = get_namespaces(xsd_string)
    # get the default namespace
    default_prefix = get_default_prefix(namespaces)
    # build xpath to element
    xpath = xpath.replace(default_prefix + ":", LXML_SCHEMA_NAMESPACE)

    type_name = default_prefix + ':' + element_type_name
    xsd_tree.find(xpath).append(
        XSDTree.create_element("{}element".format(LXML_SCHEMA_NAMESPACE),
                               attrib={
                                   'type': type_name,
                                   'name': element_type_name
                               }))
    # validate XML schema
    error = validate_xml_schema(xsd_tree)

    # if errors, raise exception
    if error is not None:
        raise XMLError(error)

    return XSDTree.tostring(xsd_tree)
    def extract_html_from_table(table_name, table):
        """Transform table into HTML string

        Args:
            table_name:
            table:

        Returns:

        """
        if not ExcelUploaderModule.is_table_valid(table_name, table):
            return "Table has not been uploaded or is not of correct format."

        table_element = XSDTree.create_element("table")
        table_element.set("class", "table table-striped excel-file")
        header = XSDTree.create_sub_element(table_element, "thead")
        header_row = XSDTree.create_sub_element(header, "tr")

        for header_name in table["headers"]:
            header_cell = XSDTree.create_sub_element(header_row, "th")
            header_cell.text = header_name

        values = XSDTree.create_sub_element(table_element, "tbody")

        for value_list in table["values"]:
            value_row = XSDTree.create_sub_element(values, "tr")

            for value in value_list:
                value_cell = XSDTree.create_sub_element(value_row, "td")
                value_cell.text = value

        div = XSDTree.create_element("div")
        div.set("class", "excel_table")
        div.append(table_element)

        return XSDTree.tostring(div)
    def extract_xml_from_table(table_name, table):
        """Transform table into XML string

        Args:
            table_name:
            table:

        Returns:

        """
        if not ExcelUploaderModule.is_table_valid(table_name, table):
            return ""

        root = XSDTree.create_element("table")
        root.set("name", table_name)
        header = XSDTree.create_sub_element(root, "headers")
        values = XSDTree.create_sub_element(root, "rows")

        col_index = 0
        for header_name in table["headers"]:
            header_cell = XSDTree.create_sub_element(header, "column")

            header_cell.set("id", str(col_index))
            header_cell.text = header_name

            col_index += 1

        row_index = 0
        for value_list in table["values"]:
            value_row = XSDTree.create_sub_element(values, "row")
            value_row.set("id", str(row_index))
            col_index = 0

            for value in value_list:
                value_cell = XSDTree.create_sub_element(value_row, "column")

                value_cell.set("id", str(col_index))
                value_cell.text = value

                col_index += 1

            row_index += 1

        xml_string = XSDTree.tostring(header)
        xml_string += XSDTree.tostring(values)

        return xml_string
示例#4
0
def _create_xsd_element(tag, attrib):
    """Create an XSD element.

    Args:
        tag:
        attrib:

    Returns:

    """

    if tag not in ["element", "include", "import"]:
        raise CoreError("Unable to create XSD element: invalid tag")

    xsd_element = XSDTree.create_element("{0}{1}".format(
        LXML_SCHEMA_NAMESPACE, tag),
                                         attrib=attrib)

    return xsd_element
示例#5
0
def _insert_element_type(xsd_string, xpath, type_content, element_type_name,
                         include_url):
    """Insert an element of given type in xsd string.

    Args:
        xsd_string: xsd string
        xpath: xpath where to insert the element
        type_content: string content of the type to insert
        element_type_name: name of the type
        include_url: url used to reference the type in schemaLocation

    Returns:

    """
    # build the dom tree of the schema being built
    xsd_tree = XSDTree.build_tree(xsd_string)
    # get namespaces information for the schema
    namespaces = get_namespaces(xsd_string)
    # get the default namespace
    default_prefix = get_default_prefix(namespaces)
    # get target namespace information
    target_namespace, target_namespace_prefix = get_target_namespace(
        xsd_tree, namespaces)
    # build xpath to element
    xpath = xpath.replace(default_prefix + ":", LXML_SCHEMA_NAMESPACE)
    # build xsd tree
    type_xsd_tree = XSDTree.build_tree(type_content)
    # get namespaces information for the type
    type_namespaces = get_namespaces(type_content)
    # get target namespace information
    type_target_namespace, type_target_namespace_prefix = get_target_namespace(
        type_xsd_tree, type_namespaces)

    # get the type from the included/imported file
    # If there is a complex type
    element_type = type_xsd_tree.find(
        "{}complexType".format(LXML_SCHEMA_NAMESPACE))
    if element_type is None:
        # If there is a simple type
        element_type = type_xsd_tree.find(
            "{}simpleType".format(LXML_SCHEMA_NAMESPACE))
    type_name = element_type.attrib["name"]

    # format type name to avoid forbidden xml characters
    element_type_name = _get_valid_xml_name(element_type_name)

    # variable that indicates if namespaces map needs to be updated
    update_ns_map = False

    # Schema without target namespace
    if target_namespace is None:
        # Type without target namespace
        if type_target_namespace is None:
            # create type name with namespace
            ns_type_name = type_name
            # create include element
            dependency_tag = "include"
            dependency_attrib = {"schemaLocation": include_url}
        # Type with target namespace
        else:
            # create type name with namespace
            ns_type_name = _get_ns_type_name(type_target_namespace_prefix,
                                             type_name,
                                             prefix_required=True)
            # create import element
            dependency_tag = "import"
            dependency_attrib = {
                "schemaLocation": include_url,
                "namespace": type_target_namespace,
            }
            update_ns_map = True

    # Schema with target namespace
    else:
        # Type without target namespace
        if type_target_namespace is None:
            # create type name with namespace
            ns_type_name = _get_ns_type_name(target_namespace_prefix,
                                             type_name)
            # create include element
            dependency_tag = "include"
            dependency_attrib = {"schemaLocation": include_url}
        # Type with target namespace
        else:
            # Same target namespace as base template
            if target_namespace == type_target_namespace:
                # create type name with namespace
                ns_type_name = _get_ns_type_name(target_namespace_prefix,
                                                 type_name)
                # create include element
                dependency_tag = "include"
                dependency_attrib = {"schemaLocation": include_url}
            # Different target namespace as base template
            else:
                # create type name with namespace
                ns_type_name = _get_ns_type_name(type_target_namespace_prefix,
                                                 type_name,
                                                 prefix_required=True)
                # create import element
                dependency_tag = "import"
                dependency_attrib = {
                    "schemaLocation": include_url,
                    "namespace": type_target_namespace,
                }
                update_ns_map = True

    # create dependency element
    dependency_element = _create_xsd_element(dependency_tag, dependency_attrib)
    # create xsd element
    xsd_element = _create_xsd_element("element",
                                      attrib={
                                          "name": element_type_name,
                                          "type": ns_type_name
                                      })
    # check if dependency element (include/import) is already present
    dependency_tag = "{0}[@schemaLocation='{1}']".format(
        dependency_element.tag, dependency_element.attrib["schemaLocation"])
    dependency_present = xsd_tree.find(dependency_tag) is not None

    if not dependency_present:
        # add dependency element (include/import)
        xsd_tree.getroot().insert(0, dependency_element)

    # add xsd element
    xsd_tree.find(xpath).append(xsd_element)

    # if namespace map of the schema needs to be updated
    if not dependency_present and update_ns_map:
        root = xsd_tree.getroot()
        root_ns_map = root.nsmap

        if (type_target_namespace_prefix in list(root_ns_map.keys())
                and root_ns_map[type_target_namespace_prefix] !=
                type_target_namespace):
            raise CoreError(
                "The namespace prefix is already declared for a different namespace."
            )
        else:
            root_ns_map[type_target_namespace_prefix] = type_target_namespace
            new_root = XSDTree.create_element(root.tag,
                                              nsmap=root_ns_map,
                                              attrib=root.attrib)
            new_root[:] = root[:]

            # return result tree
            return new_root

    else:
        # return result tree
        return xsd_tree