@@ -386,6 +386,85 @@ def _apply_3to4_conversion(self, old: Element, new: Element) -> None:
386
386
to_update [p ] = v
387
387
self .old_to_new .path .update (to_update )
388
388
389
+ # GH#59: To improve further the conversion of DD3 to DD4, especially the
390
+ # Machine Description part of the IDSs, we would like to add a 3to4 specific
391
+ # rule to convert any siblings name + identifier (that are not part of an
392
+ # identifier structure, meaning that there is no index sibling) into
393
+ # description + name. Meaning:
394
+ # parent/name (DD3) -> parent/description (DD4)
395
+ # parent/identifier (DD3) -> parent/name (DD4)
396
+ # Only perform the mapping if the corresponding target fields exist in the
397
+ # new DD and if we don't already have a mapping for the involved paths.
398
+ try :
399
+ old_paths = {f .get ("path" ): f for f in old .iterfind (".//field" )}
400
+ new_paths = {f .get ("path" ): f for f in new .iterfind (".//field" )}
401
+ except Exception :
402
+ old_paths = {}
403
+ new_paths = {}
404
+
405
+ for p in list (old_paths .keys ()):
406
+ # look for name children
407
+ if not p .endswith ("/name" ):
408
+ continue
409
+ parent = p .rsplit ("/" , 1 )[0 ]
410
+ name_path = f"{ parent } /name"
411
+ id_path = f"{ parent } /identifier"
412
+ index_path = f"{ parent } /index"
413
+ desc_path = f"{ parent } /description"
414
+ new_name_path = f"{ parent } /name"
415
+
416
+ if name_path not in old_paths or id_path not in old_paths :
417
+ continue
418
+ # exclude identifier-structure (has index sibling)
419
+ if index_path in old_paths :
420
+ continue
421
+
422
+ # Ensure the candidate target fields exist in the new DD
423
+ if desc_path not in new_paths or new_name_path not in new_paths :
424
+ continue
425
+
426
+ # Map DD3 name -> DD4 description
427
+ if name_path not in self .old_to_new .path :
428
+ old_item = old_paths [name_path ]
429
+ new_item = new_paths [desc_path ]
430
+ self .old_to_new .path [name_path ] = desc_path
431
+ self .old_to_new .tbp [name_path ] = _get_tbp (new_item , new_paths )
432
+ self .old_to_new .ctxpath [name_path ] = _get_ctxpath (desc_path , new_paths )
433
+ # reciprocal mapping
434
+ if desc_path not in self .new_to_old .path :
435
+ self .new_to_old .path [desc_path ] = name_path
436
+ self .new_to_old .tbp [desc_path ] = _get_tbp (old_item , old_paths )
437
+ self .new_to_old .ctxpath [desc_path ] = _get_ctxpath (
438
+ name_path , old_paths
439
+ )
440
+ logger .info (
441
+ "Renamed DD3 name to DD4 description %s," ,
442
+ old_item .get ("path" ),
443
+ )
444
+
445
+ # Map DD3 identifier -> DD4 name
446
+ if id_path in self .old_to_new .path :
447
+ old_item_id = old_paths [id_path ]
448
+ new_item_name = new_paths [new_name_path ]
449
+ self .old_to_new .path [id_path ] = new_name_path
450
+ self .old_to_new .tbp [id_path ] = _get_tbp (new_item_name , new_paths )
451
+ self .old_to_new .ctxpath [id_path ] = _get_ctxpath (
452
+ new_name_path , new_paths
453
+ )
454
+ # reciprocal mapping
455
+ if new_name_path not in self .new_to_old .path :
456
+ self .new_to_old .path [new_name_path ] = id_path
457
+ self .new_to_old .tbp [new_name_path ] = _get_tbp (
458
+ old_item_id , old_paths
459
+ )
460
+ self .new_to_old .ctxpath [new_name_path ] = _get_ctxpath (
461
+ id_path , old_paths
462
+ )
463
+ logger .info (
464
+ "Renamed DD3 identifier to DD4 name %s," ,
465
+ old_item_id .get ("path" ),
466
+ )
467
+
389
468
def _map_missing (self , is_new : bool , missing_paths : Set [str ]):
390
469
rename_map = self .new_to_old if is_new else self .old_to_new
391
470
# Find all structures which have a renamed sub-item
0 commit comments