Skip to content

Commit b2ac3cd

Browse files
authored
Merge pull request #555 from opengisch/model_parsing
Smarter parsing for models in xtf
2 parents ea73cf9 + f976868 commit b2ac3cd

File tree

1 file changed

+48
-17
lines changed

1 file changed

+48
-17
lines changed

QgisModelBaker/gui/workflow_wizard/wizard_tools.py

Lines changed: 48 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
import os
2222
import re
23-
import xml.etree.ElementTree as ET
23+
import xml.etree.cElementTree as CET
2424
from enum import Enum
2525

2626
from qgis.PyQt.QtCore import QSortFilterProxyModel, QStringListModel, Qt, pyqtSignal
@@ -210,7 +210,7 @@ def refresh_model(self, source_model, db_connector=None, silent=False):
210210
),
211211
Qt.Checked,
212212
)
213-
if enabled
213+
if enabled and modelname not in self.checked_models()
214214
else Qt.Unchecked,
215215
enabled,
216216
)
@@ -248,7 +248,9 @@ def refresh_model(self, source_model, db_connector=None, silent=False):
248248
),
249249
),
250250
Qt.Checked
251-
if model is models[-1] and enabled
251+
if model is models[-1]
252+
and enabled
253+
and model["name"] not in self.checked_models()
252254
else Qt.Unchecked,
253255
),
254256
enabled,
@@ -286,7 +288,9 @@ def refresh_model(self, source_model, db_connector=None, silent=False):
286288
int(SourceModel.Roles.PATH)
287289
),
288290
),
289-
Qt.Checked if enabled else Qt.Unchecked,
291+
Qt.Checked
292+
if enabled and model["name"] not in self.checked_models()
293+
else Qt.Unchecked,
290294
),
291295
enabled,
292296
)
@@ -304,21 +308,48 @@ def refresh_model(self, source_model, db_connector=None, silent=False):
304308
return self.rowCount()
305309

306310
def _transfer_file_models(self, xtf_file_path):
311+
"""
312+
Get model names from an XTF file. Since XTF can be very large, we follow this strategy:
313+
1. Parse line by line.
314+
1.a. Compare parsed line with the regular expression to get the Header Section.
315+
1.b. If found, stop parsing the XTF file and go to 2. If not found, append the new line to parsed lines and go
316+
to next line.
317+
2. Give the Header Section to an XML parser and extract models. Note that we don't give the full XTF file to the XML
318+
parser because it will read it completely, which may be not optimal.
319+
:param xtf_path: Path to an XTF file
320+
:return: List of model names from the XTF
321+
"""
307322
models = []
308-
try:
309-
root = ET.parse(xtf_file_path).getroot()
310-
for model_element in root.iter("{http://www.interlis.ch/INTERLIS2.3}MODEL"):
311-
model = {}
312-
model["name"] = model_element.get("NAME")
313-
models.append(model)
314-
except ET.ParseError as e:
315-
self.print_info.emit(
316-
self.tr(
317-
"Could not parse transferfile file `{file}` ({exception})".format(
318-
file=xtf_file_path, exception=str(e)
323+
pattern = re.compile(r"(<HEADERSECTION[^>]*.*</HEADERSECTION>)")
324+
325+
text_found = "<foo/>"
326+
with open(xtf_file_path, "r") as f:
327+
lines = ""
328+
for line in f:
329+
lines += line
330+
res = re.search(pattern, lines)
331+
if res:
332+
text_found = str(res.groups()[0])
333+
break
334+
335+
if text_found:
336+
try:
337+
root = CET.fromstring(text_found)
338+
element = root.find("MODELS")
339+
if element:
340+
for sub_element in element:
341+
if "NAME" in sub_element.attrib:
342+
model = {}
343+
model["name"] = sub_element.attrib["NAME"]
344+
models.append(model)
345+
except CET.ParseError as e:
346+
self.print_info.emit(
347+
self.tr(
348+
"Could not parse transferfile file `{file}` ({exception})".format(
349+
file=xtf_file_path, exception=str(e)
350+
)
319351
)
320352
)
321-
)
322353
return models
323354

324355
def _db_modelnames(self, db_connector=None):
@@ -394,7 +425,7 @@ def import_sessions(self):
394425
model = item.data(int(SourceModel.Roles.NAME))
395426
source = (
396427
item.data(int(SourceModel.Roles.PATH))
397-
if type != "model"
428+
if type == "ili"
398429
else "repository " + model
399430
)
400431

0 commit comments

Comments
 (0)