Exemple #1
0
    def load_xes(self):
        try:
            with open(self.input_path) as log_file:
                log = XUniversalParser().parse(log_file)[0]

            # get classifiers
            classifiers = []
            for cl in log.get_classifiers():
                classifiers.append(str(cl))

            classifier = XEventAttributeClassifier("activity", [classifiers[0]])
            log_list = list(map(lambda trace: list(map(classifier.get_class_identity, trace)), log))

            self._event_log = set(tuple(trace) for trace in log_list)

        except:
            raise IOError('[ERROR]: Unable to import xes file')
Exemple #2
0
class XMxmlParser:
    """Parser for the MXML format for event logs (deprecated).

    :param factory: The factory to use for XES model building.
    :type factory: XFactory
    """
    MXML_CLASSIFIERS = [
        XEventAttributeClassifier("MXML Legacy Classifier",
                                  ["concept:name", "lifecycle:transition"]),
        XEventNameClassifier(),
        XEventResourceClassifier()
    ]

    def __init__(self, factory=None):
        if factory:
            self.factory = factory
        else:
            self.factory = XFactoryRegistry().current_default()

    def can_parse(self, file):
        """Checks whether this parser can handle the given file.

        :param file: path of the file to check against parser.
        :type file: str
        :return: Whether this parser can handle the given file.
        :rtype: bool
        """
        return self.ends_with_ignore_case(
            file, ".mxml") or self.ends_with_ignore_case(file, ".xml")

    def parse(self, file):
        """Parses a set of logs from the given input stream, which is supposed
        to deliver an MXML serialization.



        :param file: file generated by the function 'open(path)', which is
          supposed to deliver an MXML serialization.
        :type file: _io.TextIOWrapper
        :return: The parsed list of logs.
        :rtype: list[XLog]
        """
        handler = XMxmlParser.MxmlHandler()

        xml_parse(file, handler)

        return handler.get_logs()

    @staticmethod
    def ends_with_ignore_case(name, suffix):
        """Returns whether the given file name ends (ignoring the case) with the given suffix.

        :param name: The given file name.
        :type name: str
        :param suffix: The given suffix.
        :type suffix: str
        :return: Whether the given file name ends (ignoring the case) with the given suffix.
        :rtype: bool
        """
        i = len(name) - len(suffix)
        if i > 0:
            return suffix in name[i:]
        return False

    class MxmlHandler(ContentHandler):
        """SAX handler class for XES in XML representation.

        """
        def __init__(self):
            super().__init__()
            self.__buffer = list()
            self.__logs = list()
            self.__currentProcess = None
            self.__currentInstance = None
            self.__entry = None
            self.__sourceAttribute = None
            self.__genericAttribute = None
            self.__eventTypeAttribute = None
            self.__originatorAttribute = None
            self.__sourceOpen = False
            self.__timestamp = None
            self.__lastTimestamp = None
            self.__numUnorderedEntries = 0

        def get_logs(self):
            """Retrieves the parsed list of logs.

            :return: The parsed list of logs.
            :rtype: list[XLog]
            """
            return self.__logs

        def startElement(self, element_name, attributes):
            """ Overrides startElement in class ContentHandler

            :param element_name: Contains the raw XML 1.0 name of the element type.
            :type element_name: str
            :param attributes: An instance of the Attributes class containing
              the attributes of the element
            :type attributes: xml.sax.xmlreader.AttributesImpl
            """
            tag_name = element_name
            if tag_name != "WorkflowLog":
                if tag_name == "Source":
                    self.__sourceOpen = True
                    description_string = attributes.get("program")
                    self.__sourceAttribute = XMxmlParser(
                    ).factory.create_attribute_literal("source",
                                                       description_string,
                                                       None)
                    self.__add_model_reference__(attributes,
                                                 self.__sourceAttribute)
                elif tag_name == "Process":
                    description_string = attributes.get("id")
                    description = attributes.get("description")

                    self.__currentProcess = XMxmlParser().factory.create_log()
                    self.__currentProcess.get_extensions().add(
                        XConceptExtension())
                    self.__currentProcess.get_extensions().add(
                        XOrganizationalExtension())
                    self.__currentProcess.get_extensions().add(
                        XLifecycleExtension())
                    self.__currentProcess.get_extensions().add(
                        XSemanticExtension())
                    self.__currentProcess.get_extensions().add(
                        XTimeExtension())
                    if self.__sourceAttribute:
                        self.__currentProcess.get_attributes()[
                            self.__sourceAttribute.get_key(
                            )] = self.__sourceAttribute

                    XConceptExtension().assign_name(self.__currentProcess,
                                                    description_string)
                    XLifecycleExtension().assign_model(self.__currentProcess,
                                                       "standard")

                    if description and len(description.lower()) > 0:

                        description1 = XMxmlParser(
                        ).factory.create_attribute_literal(
                            "description", description, None)
                        self.__currentProcess.get_attributes()[
                            description1.get_key()] = description1

                    self.__add_model_reference__(attributes,
                                                 self.__currentProcess)

                elif tag_name == "ProcessInstance":
                    self.__currentInstance = XMxmlParser(
                    ).factory.create_trace()
                    name = attributes.get("id")
                    if name is None:
                        name = "None"

                    XConceptExtension().assign_name(self.__currentInstance,
                                                    name)
                    description_string = attributes.get("description")

                    if description_string and len(
                            description_string.strip()) > 0:
                        description2 = XMxmlParser(
                        ).factory.create_attribute_literal(
                            "description", description_string, None)
                        self.__currentInstance.get_attributes()[
                            description2.get_key()] = description2

                    self.__add_model_reference__(attributes,
                                                 self.__currentInstance)

                elif tag_name == "AuditTrailEntry":
                    self.__entry = XMxmlParser().factory.create_event()

                elif tag_name == "Attribute":
                    self.__genericAttribute = XMxmlParser(
                    ).factory.create_attribute_literal(
                        attributes.get("name").strip(), "DEFAULT_VALUE", None)
                    self.__add_model_reference__(attributes,
                                                 self.__genericAttribute)

                elif tag_name == "EventType":
                    self.__eventTypeAttribute = XLifecycleExtension(
                    ).ATTR_TRANSITION.clone()
                    unknown_type = attributes.get("unknowntype")
                    if unknown_type:
                        self.__eventTypeAttribute.set_value(unknown_type)
                    else:
                        self.__eventTypeAttribute.set_value("UNKNOWN")

                    self.__add_model_reference__(attributes,
                                                 self.__eventTypeAttribute)

                elif tag_name == "WorkflowModelElement":
                    self.__add_model_reference__(attributes, self.__entry)

                elif tag_name == "Originator":
                    self.__originatorAttribute = XOrganizationalExtension(
                    ).ATTR_RESOURCE.clone()
                    self.__add_model_reference__(attributes,
                                                 self.__originatorAttribute)

        def endElement(self, local_name):
            """ Overrides endElement in class ContentHandler

            :param local_name: The name of the element type, just as with the startElement event
            :type local_name: str
            """
            tag_name = local_name

            if tag_name == "WorkflowLog":
                if self.__numUnorderedEntries > 0:
                    XLogging().log(
                        "LogData: Log contains " +
                        str(self.__numUnorderedEntries) +
                        " audit trail entries in non-natural order!",
                        XLogging.Importance.ERROR)
                    XLogging().log(
                        "LogData: The log file you have loaded is not MXML compliant! (error compensated transparently)",
                        XLogging.Importance.ERROR)

            elif tag_name == "Process":
                self.__currentProcess.get_classifiers().extend(
                    XMxmlParser.MXML_CLASSIFIERS)
                self.__currentProcess.get_global_trace_attributes().append(
                    XConceptExtension().ATTR_NAME.clone())
                self.__currentProcess.get_global_event_attributes().append(
                    XConceptExtension().ATTR_NAME.clone())
                self.__currentProcess.get_global_event_attributes().append(
                    XLifecycleExtension().ATTR_TRANSITION.clone())
                self.__logs.append(self.__currentProcess)
                self.__currentProcess = None

            elif tag_name == "Process":
                self.__sourceOpen = False

            elif tag_name == "ProcessInstance":
                if len(self.__currentInstance) > 0:
                    self.__currentProcess.append(self.__currentInstance)

                self.__currentInstance = None
                self.__lastTimestamp = None

            elif tag_name == "AuditTrailEntry":
                if self.__timestamp is None:
                    self.__currentInstance.append(self.__entry)
                elif self.__lastTimestamp is None:
                    self.__currentInstance.append(self.__entry)
                    self.__lastTimestamp = self.__timestamp
                elif self.__timestamp > self.__lastTimestamp:
                    self.__currentInstance.append(self.__entry)
                    self.__lastTimestamp = self.__timestamp
                else:
                    self.__currentInstance.append(self.__entry)

                self.__entry = None

            else:
                if tag_name == "Attribute":
                    originator = "".join(self.__buffer).strip()
                    if len(originator) > 0:
                        self.__genericAttribute.set_value("".join(
                            self.__buffer).strip())
                        if self.__entry:
                            self.__entry.get_attributes()[
                                self.__genericAttribute.get_key(
                                )] = self.__genericAttribute
                        elif self.__currentInstance:
                            self.__currentInstance.get_attributes()[
                                self.__genericAttribute.get_key(
                                )] = self.__genericAttribute
                        elif self.__currentProcess:
                            self.__currentProcess.get_attributes()[
                                self.__genericAttribute.get_key(
                                )] = self.__genericAttribute
                        elif self.__sourceOpen:
                            self.__sourceAttribute.get_attributes()[
                                self.__genericAttribute.get_key(
                                )] = self.__genericAttribute
                    self.__genericAttribute = None

                elif tag_name == "EventType":
                    if self.__eventTypeAttribute.get_value() == "UNKNOWN":
                        originator = "".join(self.__buffer).strip()
                        if len(originator) > 0:
                            self.__eventTypeAttribute.set_value(originator)
                            self.__entry.get_attributes()[
                                self.__eventTypeAttribute.get_key(
                                )] = self.__eventTypeAttribute
                    else:
                        self.__entry.get_attributes()[
                            self.__eventTypeAttribute.get_key(
                            )] = self.__eventTypeAttribute
                    self.__eventTypeAttribute = None

                elif tag_name == "WorkflowModelElement":
                    XConceptExtension().assign_name(
                        self.__entry, "".join(self.__buffer).strip())

                elif tag_name == "Timestamp":
                    originator = "".join(self.__buffer).strip()
                    self.__timestamp = parse_date_time(originator)
                    if self.__timestamp:
                        timestamp_attribute = XTimeExtension(
                        ).ATTR_TIMESTAMP.clone()
                        timestamp_attribute.set_value(self.__timestamp)
                        self.__entry.get_attributes(
                        )[timestamp_attribute.get_key()] = timestamp_attribute

                elif tag_name == "Originator":
                    originator = "".join(self.__buffer).strip()
                    if len(originator) > 0:
                        self.__originatorAttribute.set_value(originator)

                    self.__entry.get_attributes()[
                        self.__originatorAttribute.get_key(
                        )] = self.__originatorAttribute
                    self.__originatorAttribute = None

            self.__buffer.clear()

        @staticmethod
        def __add_model_reference__(attrib, subject):
            try:
                model_reference = attrib.getValue("modelReference")
            except KeyError:
                model_reference = None

            if model_reference:
                attribute = XSemanticExtension().ATTR_MODELREFERENCE.clone()
                attribute.set_value(model_reference)
                subject.get_attributes()[attribute.get_key()] = attribute

        def ignorableWhitespace(self, whitespace):
            """ Overrides ignorableWhitespace in class ContentHandler

            :param whitespace: The whitespace characters.
            :type whitespace: str
            """
            self.__buffer.append(whitespace)

        def characters(self, content):
            """ Overrides characters in class ContentHandler

            :param content: The characters.
            :type content: str
            """
            self.__buffer.append(content)
Exemple #3
0
class XLogInfo:
    """This class implements a bare-bones log info summary which can be created
    on demand by using applications. The log info summary is based on an event
    classifier, which is used to identify event class abstractions.

    :param log: The event log to create an info summary for.
    :type log: XLog
    :param default_classifier: The default event classifier to be used
    :type default_classifier: XEventAttributeClassifier
    :param classifiers: A collection of additional event classifiers to be
     covered by the created log info instance.
    :type classifiers: list[XEventAttributeClassifier]
    """
    STANDARD_CLASSIFIER = XEventAttributeClassifier(
        "MXML Legacy Classifier", ["concept:name", "lifecycle:transition"])
    NAME_CLASSIFIER = XEventNameClassifier()
    RESOURCE_CLASSIFIER = XEventResourceClassifier()
    LIFECYCLE_TRANSITION_CLASSIFIER = XEventLifeTransClassifier()

    @staticmethod
    def create(log, default_classifier=None, classifiers=None):
        """Creates a new log info summary with the standard event classifier.

        :param log: The event log to create an info summary for.
        :type log: XLog
        :param default_classifier: The default event classifier to be used
        :type default_classifier: XEventAttributeClassifier
        :param classifiers: A collection of additional event classifiers to be
         covered by the created log info instance.
        :type classifiers: list[XEventAttributeClassifier]
        :return: The log info summary for this log.
        :rtype: XLogInfo
        """
        if default_classifier is None:
            return XLogInfo(log, XLogInfo.STANDARD_CLASSIFIER, classifiers)
        return XLogInfo(log, default_classifier, classifiers)

    def __init__(self, log, default_classifier, classifiers):
        self.__log = log
        self.__default_classifier = default_classifier
        if classifiers is None:
            classifiers = list()
        self.__event_classes = dict()
        for classifier in classifiers:
            self.__event_classes[classifier] = XEventClasses(classifier)

        self.__event_classes[self.__default_classifier] = XEventClasses(
            self.__default_classifier)
        self.__event_classes[self.NAME_CLASSIFIER] = XEventClasses(
            self.NAME_CLASSIFIER)
        self.__event_classes[self.RESOURCE_CLASSIFIER] = XEventClasses(
            self.RESOURCE_CLASSIFIER)
        self.__event_classes[
            self.LIFECYCLE_TRANSITION_CLASSIFIER] = XEventClasses(
                self.LIFECYCLE_TRANSITION_CLASSIFIER)

        self.__number_of_events = 0
        self.__number_of_traces = 0
        self.__log_boundaries = XTimeBounds()
        self.__trace_boundaries = dict()
        self.__log_attribute_info = XAttributeInfo()
        self.__trace_attribute_info = XAttributeInfo()
        self.__event_attribute_info = XAttributeInfo()
        self.__meta_attribute_info = XAttributeInfo()
        self.setup()

    def setup(self):
        """Creates the internal data structures of this summary on setup from
        the log.

        """
        self.register_attributes(self.__log_attribute_info, self.__log)

        for trace in self.__log:
            self.__number_of_traces += 1
            self.register_attributes(self.__trace_attribute_info, trace)
            trace_bounds = XTimeBounds()

            for event in trace:
                self.__number_of_events += 1
                self.register_attributes(self.__event_attribute_info, event)

                for classes in self.__event_classes.values():
                    classes.register(event)

                trace_bounds.register(event)

            self.__trace_boundaries[trace] = trace_bounds
            self.__log_boundaries.register(trace_bounds)

        for classes in self.__event_classes.values():
            classes.harmonize_indices()

    def register_attributes(self, attribute_info, attributable):
        """Registers all attributes of a given attributable, i.e. model type
        hierarchy element, in the given attribute info registry.

        :param attribute_info: Attribute info registry to use for registration.
        :type attribute_info: XAttributeInfo
        :param attributable: Attributable whose attributes to register.
        :type attributable: XAttributable
        """
        if attributable.has_attributes():
            for attribute in attributable.get_attributes().values():
                attribute_info.register(attribute)
                self.register_attributes(self.__meta_attribute_info, attribute)

    def get_log(self):
        """Retrieves the log used for this summary.

        :return: The event log which this summary describes.
        :rtype: XLog
        """
        return self.__log

    def get_number_of_event(self):
        """Retrieves the total number of events in this log.

        :return: Total number of events.
        :rtype: int
        """
        return self.__number_of_events

    def get_number_of_traces(self):
        """Retrieves the number of traces in this log.

        :return: Number of traces available in this log.
        :rtype: int
        """
        return self.__number_of_traces

    def get_event_classes(self, classifier=None):
        """Retrieves the event classes for a given classifier.
        *Note:* The given event classifier must be covered by this log info,
        i.e., the log info must have been created with this classifier.
        Otherwise, this method will return null. You can retrieve the collection
        of event classifiers covered by this log info instance by calling the
        method getEventClassifiers().

        :param classifier: The classifier for which to retrieve the event classes.
        :type classifier: XEventAttributeClassifier or None
        :return: The requested event classes, or null if the given event
         classifier is not covered by this log info instance.
        :rtype: XEventClasses
        """
        if classifier is None:
            return self.__event_classes.get(self.__default_classifier)
        return self.__event_classes.get(classifier)

    def get_event_classifiers(self):
        """Retrieves the set of event classifiers covered by this log info,
        i.e., for which event classes are registered in this log info instance.

        :return: The tuple of event classifiers covered by this log info instance.
        :rtype: tuple
        """
        return set(self.__event_classes.keys())

    def get_resource_classes(self):
        """Retrieves the resource classes of the summarized log.

        :return: The resource classes of the summarized log.
        :rtype: XEventClasses
        """
        return self.__event_classes.get(self.RESOURCE_CLASSIFIER)

    def get_name_classes(self):
        """Retrieves the event name classes of the summarized log.

        :return: The event name classes of the summarized log.
        :rtype: XEventClasses
        """
        return self.__event_classes.get(self.NAME_CLASSIFIER)

    def get_transition_classes(self):
        """Retrieves the lifecycle transition classes of the summarized log.

        :return: The lifecycle transition classes of the summarized log.
        :rtype: XEventClasses
        """
        return self.__event_classes.get(self.LIFECYCLE_TRANSITION_CLASSIFIER)

    def get_log_time_boundaries(self):
        """Retrieves the global timestamp boundaries of this log.

        :return: Timestamp boundaries for the complete log.
        :rtype XTimeBounds
        """
        return self.__log_boundaries

    def get_trace_time_boundaries(self, trace):
        """ Retrieves the timestamp boundaries for a specified trace.

        :param trace: Trace to be queried for.
        :return: Timestamp boundaries for the indicated trace.
        :rtype: XTimeBounds
        """
        return self.__trace_boundaries.get(trace)

    def get_log_attribute_info(self):
        """Retrieves attribute information about all attributes this log
        contains on the log level.

        :return: Attribute information on the log level.
        :rtype: XAttributeInfo
        """
        return self.__log_attribute_info

    def get_trace_attribute_info(self):
        """Retrieves attribute information about all attributes this log
        contains on the trace level.

        :return: Attribute information on the trace level.
        :rtype: XAttributeInfo
        """
        return self.__trace_attribute_info

    def get_event_attribute_info(self):
        """Retrieves attribute information about all attributes this log
        contains on the event level.

        :return: Attribute information on the event level.
        :rtype: XAttributeInfo
        """
        return self.__event_attribute_info

    def get_meta_attribute_info(self):
        """Retrieves attribute information about all attributes this log
        contains on the meta (i.e., attribute) level.

        :return: Attribute information on the meta level.
        :rtype: XAttributeInfo
        """
        return self.__meta_attribute_info
from opyenxes.classification.XEventAttributeClassifier import XEventAttributeClassifier
from opyenxes.data_in.XUniversalParser import XUniversalParser

file_path = "/home/bartlomiej/process-mining/process-mining-algorithms/event_logs/L1.xes"
output_directory = "./output/"

with open(file_path) as log_file:
    # Parse the log
    log = XUniversalParser().parse(log_file)[0]

# Generate the classifier
classifier = XEventAttributeClassifier("concept:name", ["concept:name"])

# Convert log object in array with only the Activity attribute of the event
log_list = list(
    map(lambda trace: list(map(classifier.get_class_identity, trace)), log))
Exemple #5
0
from opyenxes.model.XLog import XLog
from opyenxes.data_in.XUniversalParser import XUniversalParser
from opyenxes.classification.XEventAttributeClassifier import XEventAttributeClassifier
from opyenxes.out.XesXmlSerializer import XesXmlSerializer
from sklearn.cluster import KMeans
from opyenxes.factory.XFactory import XFactory
import random

if __name__ == '__main__':
    path = "input_log.xes"

    with open(path) as log_file:
        logs = XUniversalParser().parse(log_file)

    classifier_doctype = XEventAttributeClassifier("doctype", ["doctype"])
    classifier_subprocess = XEventAttributeClassifier("subprocess",
                                                      ["subprocess"])

    new_log = XFactory.create_log()

    for log in logs:

        random_list_of_traces = random.sample(log, 5)

        for trace in random_list_of_traces:
            list_trace = []
            new_trace = XFactory.create_trace()
            for event in trace:

                doctype = classifier_doctype.get_class_identity(event)
                subprocess = classifier_subprocess.get_class_identity(event)
Exemple #6
0
    if len(trace_a) != len(trace_b):
        return False

    for event_a, event_b in zip(trace_a, trace_b):
        if not classifier.same_event_class(event_a, event_b):
            return False

    return True


with open("xes_file/example_compress_log.xes.gz") as file:
    logs = XUniversalParser().parse(file)

log = logs[0]
new_log = log.clone()
classifier = XEventAttributeClassifier("activity", ["Activity"])
new_log.clear()

print("The log have {} traces".format(len(log)))

for trace_a in log:
    new_log_have_this_trace = False

    index = 0
    while not new_log_have_this_trace and index < len(new_log):
        trace_b = new_log[index]

        if same_trace(trace_a, trace_b, classifier):
            new_log_have_this_trace = True

        index += 1
Exemple #7
0
from opyenxes.data_in.XUniversalParser import XUniversalParser
from opyenxes.classification.XEventAttributeClassifier import XEventAttributeClassifier
from collections import defaultdict
from matplotlib import pylab as plt
import numpy as np


with open("xes_file/example_compress_log.xes.gz") as file:
    logs = XUniversalParser().parse(file)

classifier = XEventAttributeClassifier("Resource", ["Resource"])
people_dict = defaultdict(lambda: 0)
for log in logs:
    for trace in log:
        for event in trace:
            people = classifier.get_class_identity(event)
            people_dict[people] += 1

name_people = list(people_dict.keys())
posicion_y = np.arange(len(name_people))
units = list(map(lambda people: people_dict[people], name_people))
plt.barh(posicion_y, units, align ="center")
plt.yticks(posicion_y, name_people)
plt.xlabel('Number of activities')
plt.title("Activities done by people")
plt.show()
Exemple #8
0
def setClassifiers(log, classifierList):
    for classifier in classifierList:
        log.get_classifiers().append(
            XEventAttributeClassifier(classifier["name"], classifier["keys"]))
Exemple #9
0
        def startElement(self, element_name, attributes):
            """ Overrides startElement in class ContentHandler

            :param element_name: Contains the raw XML 1.0 name of the element type.
            :type element_name: str
            :param attributes: An instance of the Attributes class containing
              the attributes of the element
            :type attributes: xml.sax.xmlreader.AttributesImpl
            """
            tag_name = element_name.lower()
            if tag_name not in [
                    "string", "date", "int", "float", "boolean", "id", "list",
                    "container"
            ]:
                if tag_name == "event":
                    self.__event = XesXmlParser().factory.create_event()
                    self.__attributable_stack.append(self.__event)
                elif tag_name == "trace":
                    self.__trace = XesXmlParser().factory.create_trace()
                    self.__attributable_stack.append(self.__trace)
                elif tag_name == "log":
                    self.__log = XesXmlParser().factory.create_log()
                    self.__attributable_stack.append(self.__log)
                elif tag_name == "extension":
                    extension = None

                    prefix = attributes.get("prefix")
                    keys = attributes.get("uri")

                    if prefix is not None:
                        extension = XExtensionManager().get_by_prefix(prefix)

                    elif keys is not None:
                        extension = XExtensionManager().get_by_uri(
                            parse.urlparse(keys))

                    if extension is not None:
                        self.__log.get_extensions().add(extension)
                    else:
                        print("Unknown extension: " + keys)

                elif tag_name == "global":

                    name = attributes.get("scope")

                    if name.lower() == "trace":
                        self.__globals = self.__log.get_global_trace_attributes(
                        )
                    elif name.lower() == "event":
                        self.__globals = self.__log.get_global_event_attributes(
                        )

                elif tag_name == "classifier":
                    name = attributes.get("name")
                    keys = attributes.get("keys")
                    if name is not None and keys is not None and len(
                            name) > 0 and len(keys) > 0:
                        array = XTokenHelper.extract_tokens(keys)
                        classifier = XEventAttributeClassifier(name, array)
                        self.__log.get_classifiers().append(classifier)
            else:
                name = attributes.get("key")
                if name is None:
                    name = "UNKNOWN"

                value = attributes.get("value")
                if value is None:
                    value = ""

                keys_list = None
                if ":" in name:
                    prefix = name[:name.index(":")]
                    keys_list = XExtensionManager().get_by_prefix(prefix)

                attribute = None

                if tag_name == "string":
                    attribute = XesXmlParser(
                    ).factory.create_attribute_literal(name, value, keys_list)

                elif tag_name == "date":
                    var15 = parse_date_time(value)
                    if var15 is None:
                        return
                    attribute = XesXmlParser(
                    ).factory.create_attribute_timestamp(
                        name, var15, keys_list)

                elif tag_name == "int":
                    attribute = XesXmlParser(
                    ).factory.create_attribute_discrete(
                        name, int(value), keys_list)

                elif tag_name == "float":
                    attribute = XesXmlParser(
                    ).factory.create_attribute_continuous(
                        name, float(value), keys_list)

                elif tag_name == "boolean":
                    var16 = True if value.lower() == "true" else False
                    attribute = XesXmlParser(
                    ).factory.create_attribute_boolean(name, var16, keys_list)

                elif tag_name == "id":
                    attribute = XesXmlParser().factory.create_attribute_id(
                        name, XID.parse(value), keys_list)

                elif tag_name == "list":
                    attribute = XesXmlParser().factory.create_attribute_list(
                        name, keys_list)

                elif tag_name == "container":
                    attribute = XesXmlParser(
                    ).factory.create_attribute_container(name, keys_list)

                if attribute is not None:
                    self.__attribute_stack.append(attribute)
                    self.__attributable_stack.append(attribute)