Facing issue on Linking the Branched document to Model.

Currently, I am working on a program where I need branching of the requirement document for version 2 Model. Creation of the first branched instance of a requirement document gives new document ID as well as new requirement IDs inside the branched requirement document.
However, when I tried to link and map the branched requirement document with the existing Model, the links are broken both in Model.
I need a way to map of these requirements to the Model as well as to the Test manager without breaking the existing links of the Model.
Kindly provide your inputs on this issue where I can retain the links of the Model when branched document mapped. Thanks

Answers (1)

Artem
Artem on 25 Feb 2026 at 22:07
Edited: Artem on 25 Feb 2026 at 22:13
Why links get broken
When linking Simulink blocks and Test Cases to imported references (slreq.Reference objects), the destination ends of the links are stored (in .slmx files) as internal IDs of imported references, which are not the primary user-visible IDs of the original requirements in the external RM application. This allows our product to work consistently with references imported from different supported RM applications. When updating the previously imported .slreqx from an updated .reqif file, we rely on matching the primary IDs (known in .reqif file as "ReqIF.ForeignID") with the primary IDs of the originally imported entries in .slreqx. If the external applications generates a new set of primary IDs when branching requirement collections, our Updater cannot reconcile updated artifacts with the previously imported ones. Consequently, all unmatched incoming items are considered new, and all unmatched existing items are considered deleted. Links appear broken, because the stored internal IDs no longer exist in the updated .slreqx.
How to restore broken links
Firstly, the RM application that produced the updated .reqif file should allow to include the original source ID before branching as an additional attribute (SPEC-ATTRIBUTES entry), named something like "OrigID" or "Root ID". When this attribute is present in the updated .reqif, we can rely on it to figure out, which new value of primary ID (ReqIF.ForeingID) corresponds to which previously known ID ("Root ID").
Secondly, a backup copy of the originally imported .slreqx will be required to reconstruct the mapping from the internal linked IDs stored in .slmx to the original primary ID that has been captured as "Root ID" in the updated .reqif file. You will need an automated script that does the following for each link in each related LinkSet:
1) Check the value of link.destination(). If empty, this link is unresolved and needs to be repaired.
2) Use link.getReferenceInfo() to get the destination ID as stored in .slmx (the ID that is now unresolved).
3) Use the backup (before Update) copy of the .slreqx to find an entry (slreq.Reference) with an internal ID (Reference.SID) that matches the value found in step 2.
4) Get the value of the primary ID (Reference.Id) of the Reference identified at step 3
5) In the updated .slreqx, find an entry with "Root ID" that matches the wanted original primary ID, discovered at step 4
6) use link.setDestination() function to repair the link by redirecting it to the entry identified at step 5.
Example script that implements the above steps
Note: this is not the most efficient implementation. Consider using containers.Map to pre-build the two maps, storedInternalId => originalPrimaryId and originalPrimaryId=>newBranchedId, then iterate the links and perform repairs without searching for each next Id for each next link.
% Usage:
% >> redirectLinksByTargetID(LINKED_SET_NAME, ORIG_SET_FILEPATH, LEGACY_ID_ATTRIBUTE)
% where
% LINKED_SET_NAME is the name of the currently linked ReqSet,
% ORIG_SET_FILEPATH points to a copy of originally linked ReqSet,
% LEGACY_ID_ATTRIBUTE is the name of a custom attributes in a linked
% ReqSet that stores the originally linked (legacy) IDs.
% Example:
% >> redirectLinksByTargetID('myUpdatedSet.slreqx', 'backupBeforeUpdate.slreqx', 'Root ID')
function count = redirectLinksByTargetID(linkedReqSetName, legacyReqSetFilePath, legacyIdAttribute)
% older (originally linked) ReqSet:
assert(isfile(legacyReqSetFilePath), '%s does not exist.', legacyReqSetFilePath);
legacySet = slreq.load(legacyReqSetFilePath);
assert(~isempty(legacySet), 'Failed to load %s', legacyReqSetFilePath);
% current ReqSet with legacy IDs stored in custom attribute:
[~, linkedReqSetName] = fileparts(linkedReqSetName);
linkedReqSet = slreq.find('type', 'ReqSet', 'Name', linkedReqSetName);
assert(isscalar(linkedReqSet), 'ReqSet "%s" is not loaded.', linkedReqSetName);
attributes = linkedReqSet.CustomAttributeNames();
assert(ismember(legacyIdAttribute, attributes));
% LinkSets to work on:
linkSets = slreq.find('type', 'LinkSet');
count = 0;
for i = 1:numel(linkSets)
count = count + updateAllInLinkSet(linkSets(i), linkedReqSet, legacySet, legacyIdAttribute);
end
disp(['Processed ' num2str(numel(linkSets)) ' LinkSets, ' num2str(count) ' links updated.']);
if count > 0
disp('Remember to save modified LinkSets.');
end
end
function count = updateAllInLinkSet(linkSet, linkedReqSet, legacySet, legacyIdAttribute)
links = linkSet.getLinks();
count = 0;
for i = 1:numel(links)
count = count + updateLinkIfNeeded(links(i), linkedReqSet, legacySet, legacyIdAttribute);
end
disp([num2str(count) ' out of ' num2str(numel(links)) ' links updated in ' slreq.uri.getShortNameExt(linkSet.Filename)]);
end
function updated = updateLinkIfNeeded(link, linkedReqSet, legacySet, legacyIdAttribute)
updated = 0;
destination = link.destination();
if isempty(destination) % if not resolved
destInfo = link.getReferenceInfo();
if isTargetReqSet(destInfo.artifact, linkedReqSet.Name)
legacyDest = legacySet.find('SID', destInfo.id);
if ~isempty(legacyDest)
targetReq = linkedReqSet.find(legacyIdAttribute, legacyDest.Id);
if ~isempty(targetReq)
link.setDestination(targetReq);
updated = 1;
end
end
end
end
end
function tf = isTargetReqSet(linkedArtifact, targetSetName)
[~, destName, destExt] = fileparts(linkedArtifact);
tf = strcmp(destName, targetSetName) && ...
(isempty(destExt) || strcmp(destExt, '.slreqx'));
end

Products

Release

R2022a

Asked:

on 24 Feb 2026 at 11:44

Edited:

on 25 Feb 2026 at 22:13

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!