Correct pathing

This commit is contained in:
Daniel Kluge
2023-12-30 10:16:29 +01:00
parent 73649c5d65
commit 627f3ac730
3 changed files with 58 additions and 8 deletions
+47
View File
@@ -110,6 +110,39 @@ export default class Traverser {
return current;
}
/**
* Traverse donwards from a start element by using a path.
* @param start Start element
* @param path a JS-linke path, eg. map.entry.list[0].property
* @returns Target element at the end of the path or null if not found
* @public
*/
public static traverseByPath(start: types.Class, path: string): types.Class | null {
const ids = path.split(".");
let current: types.Class | null = start;
const regex = /(\[\d+\])+$/i
for (const idShort of ids) {
if (!idShort) continue;
if (current === null) return null;
current = Traverser.findChildByIdShort(current, idShort);
const match = regex.exec(idShort)?.[0];
if (match) {
const indexes = match.split("][").map(index => parseInt(index.replace("[", "").replace("]", "")));
for (const index of indexes) {
if (current === null || !types.isSubmodelElementList(current) || current.value === null) return null;
const next = current.value?.at(index);
if (next === undefined) return null;
current = next;
}
}
}
return current;
}
/**
* Get element by using idShorts from an submodel.
* @param env Environment to search in
@@ -124,6 +157,20 @@ export default class Traverser {
return Traverser.traverseByShortIds(sm, idShorts);
}
/**
* Get element by using a path from an submodel.
* @param env Environment to search in
* @param submodelOrIdShort Submodel element or Submodel idShort
* @param path path to traverse by
* @returns Target element at the end of the path or null if not found
* @public
*/
public static getElementByPath(env: types.Environment, submodelOrIdShort: string | types.Submodel, path: string): types.Class | null {
const sm = typeof submodelOrIdShort === "string" ? Traverser.findSMByIdShort(env, submodelOrIdShort) : submodelOrIdShort;
if (sm === null) return null;
return Traverser.traverseByPath(sm, path);
}
/**
* Find an element using a function to check.
* @param start Start element