Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Fix] added support for XES composite list attributes #469

Open
wants to merge 2 commits into
base: release
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 17 additions & 5 deletions pm4py/objects/log/importer/xes/variants/iterparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -422,10 +422,22 @@ def __parse_attribute(elem, store, key, value, tree):
store[key] = value
else:
if elem.getchildren()[0].tag.endswith(xes_constants.TAG_VALUES):
store[key] = {xes_constants.KEY_VALUE: value, xes_constants.KEY_CHILDREN: list()}
tree[elem] = store[key][xes_constants.KEY_CHILDREN]
tree[elem.getchildren()[0]] = tree[elem]
if isinstance(store, list):
store.append((key, {xes_constants.KEY_VALUE: value, xes_constants.KEY_CHILDREN: list()}))
tree[elem] = store[-1][1][xes_constants.KEY_CHILDREN]
tree[elem.getchildren()[0]] = tree[elem]
else:
store[key] = {xes_constants.KEY_VALUE: value, xes_constants.KEY_CHILDREN: list()}
tree[elem] = store[key][xes_constants.KEY_CHILDREN]
tree[elem.getchildren()[0]] = tree[elem]

else:
store[key] = {xes_constants.KEY_VALUE: value, xes_constants.KEY_CHILDREN: dict()}
tree[elem] = store[key][xes_constants.KEY_CHILDREN]
composite_att = {xes_constants.KEY_VALUE: value, xes_constants.KEY_CHILDREN: dict()}
if isinstance(store, list):
store.append((key, composite_att))
tree[elem] = store[-1][1][xes_constants.KEY_CHILDREN]
else:
store[key] = composite_att
tree[elem] = store[key][xes_constants.KEY_CHILDREN]

return tree
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ pytz
scipy
stringdist
tqdm
deepdiff
6 changes: 5 additions & 1 deletion tests/execute_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"DiagnDfConfChecking", "ProcessModelEvaluationTests", "DecisionTreeTest", "GraphsForming",
"HeuMinerTest", "MainFactoriesTest", "AlgorithmTest", "LogFilteringTest",
"DataframePrefilteringTest", "StatisticsLogTest", "StatisticsDfTest", "TransitionSystemTest",
"ImpExpFromString", "WoflanTest", "OcelFilteringTest", "OcelDiscoveryTest", "LlmTest"]
"ImpExpFromString", "WoflanTest", "OcelFilteringTest", "OcelDiscoveryTest", "LlmTest", "XesCompositeAttTest"]

loader = unittest.TestLoader()
suite = unittest.TestSuite()
Expand Down Expand Up @@ -201,6 +201,10 @@

suite.addTests(loader.loadTestsFromTestCase(LlmTest))

if "XesCompositeAttTest" in enabled_tests:
from tests.xes_composite_att_test import XesCompositeListAttributesTest

suite.addTests(loader.loadTestsFromTestCase(XesCompositeListAttributesTest))

def main():
runner = unittest.TextTestRunner()
Expand Down
23 changes: 23 additions & 0 deletions tests/input_data/composite_list_attributes.xes
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version='1.0' encoding='UTF-8'?>
<log xes.version="1849-2016" xes.features="nested-attributes" xmlns="http://www.xes-standard.org/">
<string key="Description" value="Minimal XES composite list attributes log."/>
<trace>
<event>
<list key="composite:list" >
<values>
<string key="composite:list:elementary:string:1" value="example:string:value:1" />
<string key="" value="">
<string key="composite:string" value="composite:string:value:1" />
</string>
<string key="composite:list:elementary:string:2" value="example:string:value:2" />
<list key="composite:composite:list">
<values>
<string key="composite:composite:list:elementary:string:1" value="example:string:value:1" />
<string key="composite:composite:list:elementary:string:2" value="example:string:value:2" />
</values>
</list>
</values>
</list>
</event>
</trace>
</log>
42 changes: 42 additions & 0 deletions tests/xes_composite_att_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from pm4py.objects.log.importer.xes import importer as xes_importer
from pm4py.objects.log.exporter.xes import exporter as xes_exporter
from tests.constants import (
INPUT_DATA_DIR,
OUTPUT_DATA_DIR,
)
from deepdiff import DeepDiff
import unittest
import os


class XesCompositeListAttributesTest(unittest.TestCase):
def test_minimalXESCompositeListAttributes(self):
xes_log_path = os.path.join(INPUT_DATA_DIR, "composite_list_attributes.xes")
exported_log_path = os.path.join(
OUTPUT_DATA_DIR, "composite_list_attributes.xes"
)
log = xes_importer.apply(
xes_log_path,
)

xes_exporter.apply(log, exported_log_path)
log_imported_after_export = xes_importer.apply(exported_log_path)

self.check_difference(log, log_imported_after_export)

os.remove(exported_log_path)

def check_difference(self, log_1, log_2):
difference = self.compare_logs(log_1, log_2)

if difference:
self.fail(f"Logs do not match with difference: {difference}")

def compare_logs(self, log_1, log_2):
diff = DeepDiff(log_1, log_2, ignore_order=True)
if diff:
return diff


if __name__ == "__main__":
unittest.main()