Этот пример охватывает набор стандартных ситуаций, когда ссылки между программными продуктами проекта и требованиями становятся устаревшими после перемещения или переименования одного или нескольких программных продуктов. Скорее тогда удаляя сломанные ссылки и создавая новые таковые, мы хотим обновить существующие ссылки так, чтобы история создания/изменения и другие свойства (описание, ключевые слова, комментарии,..) были сохранены. Показано использование следующих API:
slreq.find чтобы завладеть записями и ссылками Simulink Requirements ®
find для поиска требуемой записи в данном ReqSet
getLinks запрос всех исходящих ссылок в LinkSet
source краткая информация об источнике ссылки
destination краткая информация о адресате по ссылке
slreq.Link для «as stored» целевой информации, которая отличается от «as resolded» Link.destination()
slreq.LinkSet для обновления адресатов ссылок при перемещении целевого документа
slreq.ReqSet для обновления ранее импортированного набора при перемещении исходного документа
updateFromDocument для обновления ранее импортированных ссылок из обновленного документа
slreq.LinkSet для преобразования существующих «прямых ссылок» в «ссылочных ссылок»
slreq.show используется для просмотра исходного или целевого конца заданного slreq.Link
В нескольких местах мы также используем наследие rmi API, унаследованные от Requirements Management Interface (RMI) продукта SLVnV.
Прежде чем вы начнете, убедитесь в чистом начальном состоянии, запустив slreq.clear команда. Затем введите slreqCCProjectStart чтобы открыть пример проекта круиз-контроля. Это разархивирует набор связанных файлов программных продуктов в новую подпапку под вашим MATLAB/Projects папка.
slreq.clear(); slreqCCProjectStart();
Мы сосредоточимся на небольшой части этого Графика Зависимостей Проекта: откройте crs_plant.slx Модель, которая имеет несколько ссылок на внешний документ Microsoft ® Word crs_reqs.docx.
open_system('crs_plant');
Перейдите по одной из ссылок, чтобы открыть связанный документ.
rmi('view', 'crs_plant/status', 1);

Документ Word откроется в соответствующем разделе:

Вот как использовать API командной строки и проверить на наличие ссылок из crs_plant.slx на crs_reqs.docx.
linkSet = slreq.find('type', 'LinkSet', 'Name', 'crs_plant'); links = linkSet.getLinks(); disp('Original Links to Word document:');
Original Links to Word document:
for i = 1:numel(links) linkTarget = links(i).getReferenceInfo(); if contains(linkTarget.artifact, 'crs_req.docx') source = links(i).source; disp([' found link from ' strrep(getfullname([bdroot source.id]),newline,'') ... ' to crs_req.docx']); end end
found link from crs_plant/Vehicle1/vehiclespeed to crs_req.docx
found link from crs_plant/throttDrv to crs_req.docx
found link from crs_plant/status to crs_req.docx
found link from crs_plant/throttleCC to crs_req.docx
Откройте Редактор Simulink Requirements путем ввода slreq.editor в командной строке MATLAB. Вы увидите два загруженных набора требований: crs_req.slreqx и crs_req_func_spec.slreqx. Первый набор требований является коллекцией ссылок, импортированных из crs_req.docx, а второй был создан вручную в Simulink Requirements Editor. Если теперь закрыть документ Word и перейти по той же ссылке из crs_plant/status Блок Inport, соответствующая импортированная ссылка подсвечивается в редакторе требований, поскольку действие навигации находит соответствующую привязку в загруженном импортированном наборе требований.

Вы по-прежнему можете использовать кнопку Показать в документе, чтобы увидеть связанное Требование в контексте исходного документа.
slreq.editor(); rmidotnet.MSWord.application('kill'); rmi('view', 'crs_plant/status', 1);
Предположим, что получена обновленная версия документа требований с именем crs_req_v2.docx. Теперь нам нужны ссылки в crs_plant.slx для целевого задания соответствующих разделов обновленного документа. Для целей этого примера мы сделаем копию исходного документа в той же папке с измененным именем. Затем используем slreq.LinkSet API для пакетного обновления всех ссылок в заданном LinkSet для подключения к более новой копии документа:
copyfile(fullfile(pwd, 'documents/crs_req.docx'), fullfile(pwd, 'documents/crs_req_v2.docx')); linkSet.updateDocUri('crs_req.docx', 'crs_req_v2.docx');
Теперь можно перейти по той же ссылке и подтвердить открытие соответствующей версии внешнего документа. Если мы итерируем все ссылки, как и прежде, это подтверждает, что все 4 ссылки обновляются по назначению:
rmi('view', 'crs_plant/status', 1); % updated document opens links = linkSet.getLinks(); disp('Links to Word document after update:');
Links to Word document after update:
for i = 1:numel(links) source = links(i).source; linkTarget = links(i).getReferenceInfo(); if contains(linkTarget.artifact, 'crs_req.docx') warning(['link from ' source.id ' still points to crs_req.docx']); % should not happen elseif contains(linkTarget.artifact, 'crs_req_v2.docx') disp([' found link from ' strrep(getfullname([bdroot source.id]),newline,' ')... ' to crs_req_v2.docx']); end end
found link from crs_plant/Vehicle1/vehicle speed to crs_req_v2.docx
found link from crs_plant/throttDrv to crs_req_v2.docx
found link from crs_plant/status to crs_req_v2.docx
found link from crs_plant/throttleCC to crs_req_v2.docx
Как показано выше, когда импортированные ссылки доступны в редакторе требований, навигация по ссылке приведет к выбору соответствующего объекта. Однако мы только что обновили ссылки на новую версию документа crs_req_v2.docx, и нет импортированных ссылок для этого документа. Навигация из блока Simulink в присутствии редактора требований приводит вас непосредственно к внешнему документу Word.

Чтобы избежать этого несоответствия, необходимо обновить ранее импортированные ссылки для связи с обновленным именем документа. Используем slreq.ReqSet API для выполнения этой задачи. Кроме того, поскольку в обновленном документе могут быть изменены Требования, мы должны использовать updateFromDocument API для получения по запросу-в обновлений для ссылочных элементов, хранящихся на стороне Simulink Requirements. После этого навигация из модели Simulink определит местоположение совпадающей импортированной ссылки.

Найдите набор требований с импортированными ссылками. Обновите расположение исходного файла и найдите узел Импорт верхнего уровня.
reqSet = slreq.find('type', 'ReqSet', 'Name', 'crs_req'); reqSet.updateSrcFileLocation('crs_req.docx', 'crs_req_v2.docx'); importNode = reqSet.find('CustomId', 'crs_req_v2');
Обновите импортированные ссылки из исходного файла. Закройте Microsoft Word. Затем перейдите к обновленной ссылке в редакторе требований.
importNode.updateFromDocument(); rmidotnet.MSWord.application('kill'); rmi('view', 'crs_plant/status', 1);
Отменить изменения данных о ссылках, чтобы избежать запросов на закрытие проекта. Закройте проект (также очищает изменения пути MATLAB). Закройте Microsoft Word.
slreq.clear();
prj = simulinkproject(); prj.close();
rmidotnet.MSWord.application('kill'); Как показано в примере использования 1 выше, необходимы дополнительные усилия для поддержания «прямых ссылок» на внешние документы при перемещении или переименовании документов. Лучшим рабочим процессом является преобразование существующих «прямых ссылок» в «ссылочные ссылки», которые являются ссылками, указывающими на импортированные References в *.slreqx файлы и больше не дублируют информацию о местоположении или имени исходного документа. При использовании этой опции связь с внешним исходным документом сохраняется только в наборе требований, на котором размещены импортированные ссылки.
Чтобы продемонстрировать этот рабочий процесс, перезапустите из той же начальной точки, снова откроя Определение требований для Модели круиз-контроля в новой подпапке. Скопируйте модель Simulink в свою директорию и откройте его.
slreqCCProjectStart(); copyfile(fullfile(pwd, 'documents/crs_req.docx'), fullfile(pwd, 'documents/crs_req_v2.docx')); open_system('crs_plant');
Найдите crs_plant набор ссылок и crs_req набор требований с импортированными ссылками.
linkSet = slreq.find('type', 'LinkSet', 'Name', 'crs_plant'); reqSet = slreq.find('type', 'ReqSet', 'Name', 'crs_req');
Затем используем slreq.LinkSet API для обновления всех прямых ссылок в crs_plant.slmx. Затем создайте массив всех ссылок в наборе ссылок.
linkSet.redirectLinksToImportedReqs(reqSet); links = linkSet.getLinks();
После обновления LinkSet таким образом цикл по всем ссылкам, чтобы подтвердить отсутствие «прямых» ссылок на crs_req.docx файл.
disp('Check for links to original external document:');Check for links to original external document:
counter = 0; for i = 1:numel(links) linkTarget = links(i).getReferenceInfo(); if contains(linkTarget.artifact, 'crs_req.docx') source = links(i).source; warning(['link from ' source.id ' still points to crs_req.docx']); counter = counter + 1; end end disp([' Total ' num2str(counter) ' links to external document']);
Total 0 links to external document
Перейдите от модели Simulink к обновленной ссылке.
rmi('view', 'crs_plant/status', 1);
Теперь, когда все ссылки указывают на импортированные ссылки, а не на внешний документ, данную трассируемость остаются непротиворечивыми после переименования документа, пока узел Импорт обновляется для нового внешнего имени документа. Как и в Use Case 1, мы будем делать вид, что есть обновленная версия документа с внешними требованиями, придавая нашему документу Word новое имя. Затем мы выполняем необходимое обновление для узла Import, используя те же API, что и раньше. Теперь, поскольку ссылки полагаются на импортированные ссылки и не хранят информацию об импортированном документе, навигация из модели Simulink приводит нас к обновленной ссылке, так же как после выполнения всех шагов Use Case 1.

Ссылка теперь связана с обновленным внешним документом, кнопка [Показать в документе] открывает обновленный (переименованный) документ, и дальнейшая корректировка на стороне LinkSet не требуется.
Найдите набор требований с импортированными ссылками. Обновите расположение исходного файла и найдите узел Импорт верхнего уровня.
reqSet = slreq.find('type', 'ReqSet', 'Name', 'crs_req'); reqSet.updateSrcFileLocation('crs_req.docx', 'crs_req_v2.docx'); importNode = reqSet.find('CustomId', 'crs_req_v2');
Обновите импортированные ссылки из исходного файла. Затем перейдите к обновленной ссылке в редакторе требований.
importNode.updateFromDocument();
rmi('view', 'crs_plant/status', 1);
Отменить изменения данных о ссылках, чтобы избежать запросов на закрытие проекта. Закройте проект (также очищает изменения пути MATLAB). Закройте Microsoft Word.
slreq.clear();
prj = simulinkproject(); prj.close();
rmidotnet.MSWord.application('kill'); Теперь предположим, что мы разветвляем существующий проект со связанными программными продуктами, и нам нужно создать новый набор переименованных программных продуктов со всеми ссылками трассируемости, как в исходном проекте. Как и прежде, мы извлекем Проект Круиз-Контроля из Определения Требований для Модели Круиз-Контроля в новую подпапку и преобразуем «прямые ссылки» в «ссылочные ссылки», как мы сделали в Use Case 2 выше. Затем мы идем вперед и создадим «новые версии» связанных программных продуктов, сбросив каждую с _v2. имя.
После создания переименованных копий модели Simulink, импортированного внешнего документа и набора требований с импортированными требованиями возникает одна проблема: переименованная модель связана со ссылками в исходном наборе требований, а не в переименованном наборе требований. На панели Сведения (Details) в разделе Ссылки (Links) ссылки отображаются неразрешенными, поскольку исходная модель не загружена.

Откройте Проект Круиз-Контроля и откройте crs_plant модель. Найдите набор ссылок для crs_plant и набор требований crs_req.
slreqCCProjectStart(); open_system('models/crs_plant.slx'); linkSet = slreq.find('type', 'LinkSet', 'Name', 'crs_plant'); reqSet = slreq.find('type', 'ReqSet', 'Name', 'crs_req');
Преобразуйте прямые ссылки в ссылочные ссылки. Создайте переименованные копии файлов и сохраните их.
linkSet.redirectLinksToImportedReqs(reqSet); mkdir(fullfile(pwd, 'copied')); save_system('crs_plant', fullfile(pwd, 'copied/crs_plant_v2.slx')); reqSet.save(fullfile(pwd, 'copied/crs_req_v2.slreqx')); copyfile('documents/crs_req.docx', 'copied/crs_req_v2.docx');
Связать переименованный набор требований с переименованным документом. Найдите узел Импорт верхнего уровня.
reqSet.updateSrcFileLocation('crs_req.docx', fullfile(pwd, 'copied/crs_req_v2.docx')); importNode = reqSet.find('CustomId', 'crs_req_v2');
Убедитесь, что содержимое переименованного набора требований совпадает с содержимым переименованного документа путем обновления импортированных ссылок. Перейдите от переименованной модели Simulink к элементу в переименованном наборе требований. Старый элемент в исходном наборе требований подсвечивается, что неправильно.
importNode.updateFromDocument();
rmi('view', 'crs_plant_v2/status', 1);
Аналогично Use Case 1, мы можем использовать LinkSet.updateDocUri(OLD, NEW) API для обновления ссылок в crs_plant_v2.slmx для использования переименованного набора требований crs_req_v2.slreqx в качестве цели ссылки вместо исходного crs_req.slreqx. Как только это сделано, перейдите снова из блока в переименованной модели. В переименованном наборе требований выбрано требование и устранены ссылки на панели «Сведения» в разделе «Ссылки» справа внизу.

Найдите набор ссылок для новой копии модели, crs_plant_v2. Обновите имя набора требований, связанное с новой копией модели. Перейдите от переименованной модели Simulink к элементу в переименованном наборе требований. На этот раз он подсвечивает правильный элемент.
linkSet = slreq.find('type', 'LinkSet', 'Name', 'crs_plant_v2'); linkSet.updateDocUri('crs_req.slreqx', 'crs_req_v2.slreqx');
rmi('view', 'crs_plant_v2/status', 1);
Очистите открытые наборы требований и наборы ссылок и закройте открытые модели и проекты, не сохраняя изменений. Закройте Microsoft Word.
slreq.clear(); bdclose('all'); prj = simulinkproject(); prj.close(); rmidotnet.MSWord.application('kill');