嵌套模型报告+搜索结果

时间:2015-11-08 23:36:38

标签: enterprise-architect

似乎我不是第一个对此进行调查的人。但还没有绝望: - )

我想要达到的目标状态是:

  • 通过Packages的递归,其中一些嵌套的子包是美化的链接文档,有些是Grids呈现搜索结果。

我喜欢模型文档提供搜索标记值 - 但我似乎无法将网格嵌套在我希望它们显示的位置。

方法1:嵌套模型文档

如果我可以使用他们的搜索/搜索词标记嵌套Model Document个元素,我会被排序。我可以

  • 上下文:包
    • 简介:Package< - 只需呈现附加的链接文档
    • 受影响的系统:包< - 只需呈现附加到其上的链接文档
      • 受影响的系统:模型文档< - 呈现预制搜索的结果。

但EA似乎被设计为忽略Model Document元素。

方法2:SQL支持的模板片段

我喜欢模型文档,因为它具有搜索/搜索术语+所有包含/排除配置选项。但是如果我不得不放弃那部分,我正在考虑通过SQL或脚本尽可能多地模仿。

首次尝试 - 使用SQL和一组嵌套的包,例如:

  • 上下文:包
    • 简介:Package< - 只需呈现附加的链接文档
    • 受影响的系统:包< - 只需呈现附加到其上的链接文档
      • 受影响的系统:包<> < - 呈现SQL搜索的结果。

如果模板使用TemplateSelector,它可以发现具有众所周知的构造型的Package,并调用由SQL支持的模板。

SQL使用Package的关键字作为要搜索的Element类型的源。

SELECT 
o.ea_guid AS [CLASSGUID], 
o.Object_Type AS [CLASSTYPE],
o.PDATA5 AS [KEYWORDS],
o.Object_Type AS [Type],
o.Stereotype AS [Stereotype],
*
FROM t_object as O 
WHERE O.Object_Type IN 
   (SELECT PDATA5 FROM t_object AS S where S.Object_ID = #OBJECTID#)

它的作用......勉强。它有点hacky。

搜索元素类型对于生产文档来说是不够的。

方法3:脚本支持的模板片段

如果我可以运行脚本,我怀疑我可以利用系统中已有的功能。

  • 上下文:包
    • 简介:Package< - 只需呈现附加的链接文档
    • 受影响的系统:包< - 只需呈现附加到其上的链接文档
      • 受影响的系统:包<> < - 呈现预制搜索的结果。

如果模板使用TemplateSelector,它可以使用一个知名的构造型来发现Package,并调用一个由脚本支持的模板。

我尝试的脚本是:

var x = Repository.GetElementsByQuery("POC.Req", "Device");
return x;

但是报告仍然是我需要的那些元素的空白。

问:返回的Collection在使用之前是否需要转换?

方法4

我听说有一种渲染文档部分的方法是PDF,并链接到它们作为链接文档...声音卷曲。听起来像是错误/魔术的方法。

方法5

还有其他建议吗?

感谢您的帮助。

附录

通过将脚本结果转换为xml然后再将其转换为

来获得方法3

模板的脚本现在看起来像

-- first pass ...I'll work on passing the ObjectId in a bit in order to get fancier.
ExecuteSearch("Simple", "Device")

并调用其他地方保存的脚本

!INC Local Scripts.EAConstants-JScript

/*
 * Script Name: 
 * Author: 
 * Purpose: 
 * Date: 
 */

function main()
{
    return ExecuteSearch("Simple", "Device");
}

function ExecuteSearch(searchName, searchParam){
    var x = Repository.GetElementsByQuery(searchName, searchParam);
    //return x;
    var xmlDOC = CreateReport(x);
    var s = xmlDOC.xml;
    Session.Output(s);
    return s;
}

function CreateReport(entityCollection){
    var xmlDOC = CreateXmlDOC();
    var xmlRoot = AppendXmlChild(xmlDOC,"EADATA");
    var xmlDataSet = AppendXmlChild(xmlDOC,"Dataset_0",xmlRoot);
    var xmlData = AppendXmlChild(xmlDOC,"Data",xmlDataSet);

    for(var i = 0;i<entityCollection.Count();i++){
        var entity = entityCollection.GetAt(i);

        var xmlRow = AppendXmlChild(xmlDOC,"Row",xmlData);

        //AppendXmlChild(xmlDOC,"CLASSTYPE",xmlRow).Text = entity.Type;
        AppendXmlChild(xmlDOC,"Guid",xmlRow).text = entity.ElementGUID;
        AppendXmlChild(xmlDOC,"CLASSTYPE",xmlRow).text = entity.Type;
        AppendXmlChild(xmlDOC,"CLASSGUID",xmlRow).text = entity.ElementGUID;
        AppendXmlChild(xmlDOC,"Type",xmlRow).text = entity.Type;
        AppendXmlChild(xmlDOC,"Stereotype",xmlRow).text = entity.Stereotype;
        AppendXmlChild(xmlDOC,"Name",xmlRow).text = entity.Name;
        AppendXmlChild(xmlDOC,"Object",xmlRow).text = entity.Name;
        AppendXmlChild(xmlDOC,"Id",xmlRow).text = entity.ElementID;
        AppendXmlChild(xmlDOC,"Scope",xmlRow).text = entity.Scope;
        AppendXmlChild(xmlDOC,"Phase",xmlRow).text = entity.Phase;
        AppendXmlChild(xmlDOC,"Status",xmlRow).text = entity.Status;
        var noteElement = AppendXmlChild(xmlDOC,"Notes",xmlRow);//.text = entity.Notes;

        noteElement.appendChild(xmlDOC.createCDATASection(entity.Notes));
        AppendXmlChild(xmlDOC,"Keywords",xmlRow).text = entity.PDATA5;

        }

    return xmlDOC;
}

function CreateXmlDOC()
{
    var xmlDOM;
    try
    {
           xmlDOM = new ActiveXObject( "MSXML2.DOMDocument.4.0" );
    }
    catch(e)
    {
           xmlDOM = new ActiveXObject( "MSXML2.DOMDocument.6.0" );
    }

    xmlDOM.createProcessingInstruction("xml","version=\"1.0\"");
    xmlDOM.validateOnParse = false;
    xmlDOM.async = false;

    return xmlDOM;
}

function AppendXmlChild(xmlDOM, xmlElementName, xmlParent, isCDATA){
    if (!xmlParent){xmlParent = xmlDOM;}

    var child = xmlDOM.createElement(xmlElementName);
    xmlParent.appendChild(child);
    return child;
}


main();

1 个答案:

答案 0 :(得分:0)

我最后使用的脚本如下。它现在正确地调查元素的标签以寻找线索,如何继续。

希望它能帮助别人。

!INC Local Scripts.EAConstants-JScript

/*
 * Script Name: 
 * Author: 
 * Purpose: 
 * Date: 
 */

 //Only used for development
function devTest()
{
    //With Child elements: {2255D8C8-F1BB-4069-BDAF-8B303D108C62}
    //With SearchName: {919252E0-BDEB-4f26-A39F-C0E74382952A}
    //With PackageGUID: {8543ED3B-EC39-4bf0-92C2-FD49A00C376B}

    Session.Output ("DEVTEST");
    var package = Repository.GetPackageByGuid("{8543ED3B-EC39-4bf0-92C2-FD49A00C376B}");

    Session.Output("Package Name:" + package.Name);
    Session.Output("Package Guid:" + package.PackageGUID);
    Session.Output("Package Id:" + package.PackageID);
    Session.Output("Package ElementId:" + package.Element.ElementID);
    //Session.Output("Package Element Id:" + package.Element.ElementID);


    //Use the Element associate to the Package, not the Package ID itself.
    var packageElementId = package.Element.ElementID; //NOT: package.PackageID;

    var xmlDoc=ExecuteSearch(packageElementId);
    try {
        Session.Output(xmlDoc.xml);
    }catch (e){
        Session.Output(e.message);
    }

}



//Extracts from a given Package it's SearchName/SearchValue tags
//in order to do a search that mimicks a ModelDocument's way of 
//generating a report.
function ExecuteSearch(elementId){
    //Validation
    if (!elementId){
        Session.Output("Exiting: No elementId received.");
        return;
    }   

    var packageElement = Repository.GetElementByID(elementId);
    if (!packageElement){
        Session.Output("Exiting: No package with given elementId: " + elementId);
        return;
    }

    try {
        var xmlDOC = ExecuteSearch2(packageElement);
        var xml = xmlDOC.xml;
        return xml;
    }catch (e){
        Session.Output("ERROR: " + e.message);
    }
    return null;
}

function ExecuteSearch2(packageElement){

    //Session.Output(packageElement.ElementGUID + ": '" + packageElement.Name +  "' invoking ExecuteSearch(" + packageElement.ElementID  + ")");
    //Session.Output("Attribute 'Test': " + GetElementTaggedValue(packageElement,'Test'));

    //Precendence is to search 
    //* Direct children,
    //* by Package, recursively, 
    //* Package, single
    //* Package

    //First dibs: does this package have any direct elements?

    //Get back to the package that is related to the Element before you count Elements:
    var package = Repository.GetPackageByGuid(packageElement.ElementGUID);
    var elementCollection = package.Elements;
    if (elementCollection.Count()){
        Session.Output("Package [" + packageElement.ElementGUID + "] has child Elements:"+ elementCollection.Count());
        return CreateReportDoc(elementCollection);
    }

    //If package had no children, look at Attributes for reference to other package.
    //At present, can't find an easy way to determine package Id from the EA GUI, so 
    //using the Guid.
    var searchPackageGuid = GetElementTaggedValue(packageElement,'SearchPackageGUID');
    if (!searchPackageGuid){
        searchPackageGuid = GetElementTaggedValue(packageElement,'SearchPackageGuid');
    }
    if (searchPackageGuid){
        //Session.Output("Package [" + packageElement.ElementGUID + "] has SearchPackageGuid:"+ searchPackageGuid);
        return ExecuteSearchByPackageGuid(searchPackageGuid);
    }

//  //If I ever find a way to get a packageId:
    var searchPackageId =  GetElementTaggedValue(packageElement,'SearchPackageId');
    if (searchPackageId){
        //Session.Output("Package [" + packageElement.ElementGUID + "] has SearchPackageId:"+ searchPackageId);
        return ExecuteSearchByPackageId(searchPackageId);
    }

//  //If searching by SQL:
    var searchSQL =  GetElementTaggedValue(packageElement,'SearchSQL');
    if (searchSQL){
        Session.Output("Package [" + packageElement.ElementGUID + "] has SearchSQL:"+ searchSQL);
        return ExecuteSearchBySQL(searchSQL);
    }

    //Not pointing to a package, so maybe pointing to a canned search:
    var searchName =  GetElementTaggedValue(packageElement,'SearchName');
    if (!searchName){
        //Session.Output("No SearchName");
        return;
    }

    var searchValue = GetElementTaggedValue(packageElement,'SearchValue');
    //Session.Output("Package [" + packageElement.ElementGUID + "] has SearchName/Value:"+ searchName + "/" + searchValue);
    return ExecuteSearchBySearchName(searchName, searchValue);
}


//Mimicks functionality of a ModelDocument that searches by canned SearchName/SearchValue.
function ExecuteSearchBySearchName(searchName, searchValue){
    var elementCollection = Repository.GetElementsByQuery(searchName, searchValue);
    //return x;
    return CreateReportDoc(elementCollection);
}

function ExecuteSearchByPackageGuid(packageGuid){
    var package = Repository.GetPackageByGuid(packageGuid);
    return ExecuteSearch2(package.Element);
}


function ExecuteSearchBySQL(searchSQL){
    var elementCollection = Repository.GetElementSet(searchSQL, 2); 
}


function HOLD_ExecuteSearchBySet(idList){
    var elementCollection = Repository.GetElementsSet(idList);
    //return x;
    return CreateReportDoc(elementCollection);
}

//Iterate through the elements and convert to an Xml Document
//suitable for use by a Script backed Template:
function CreateReportDoc(elementCollection){
    var xmlDOC = CreateXmlDOC();
    var xmlData = CreateXmlReport(xmlDOC);

    for(var i = 0;i<elementCollection.Count();i++){
        //For each Element, create a new row:
        var xmlRow = AppendXmlChild(xmlData,"Row");
        //And embed the specific element:
        var element = elementCollection.GetAt(i);
        CreateReportRow(xmlRow, element);
    }

    return xmlDOC;
}

function CreateReportRow(xmlRow, element){
        //And attach child property elements. 
        //For hairy ones, add them as a CDATA.
        //AppendXmlChild(xmlDOC,"CLASSTYPE",xmlRow).Text = element.Type;
        AppendXmlChild(xmlRow,"Guid").text = element.ElementGUID;
        AppendXmlChild(xmlRow,"CLASSTYPE").text = element.Type;
        AppendXmlChild(xmlRow,"CLASSGUID").text = element.ElementGUID;
        AppendXmlChild(xmlRow,"Type").text = element.Type;
        AppendXmlChild(xmlRow,"Stereotype").text = element.Stereotype;
        AppendXmlChild(xmlRow,"Name").text = element.Name;
        AppendXmlChild(xmlRow,"Object").text = element.Name;
        AppendXmlChild(xmlRow,"Id").text = element.ElementID;
        AppendXmlChild(xmlRow,"Scope").text = element.Scope;
        AppendXmlChild(xmlRow,"Phase").text = element.Phase;
        AppendXmlChild(xmlRow,"Status").text = element.Status;
        AppendXmlChild(xmlRow,"Keywords").text = element.PDATA5;
        //Notes need wrapping as CDATA
        var noteElement = AppendXmlChild(xmlRow,"Notes");//.text = entity.Notes;
        noteElement.appendChild(xmlRow.ownerDocument.createCDATASection(element.Notes));
        //Now get tags:
        AppendXmlChild(xmlRow,"Tags.ID").text = GetElementTaggedValue(element,"ID");
        AppendXmlChild(xmlRow,"Tags.Type").text = GetElementTaggedValue(element,"Type");
        AppendXmlChild(xmlRow,"Tags.Category").text = GetElementTaggedValue(element,"Category");
        AppendXmlChild(xmlRow,"Tags.Traceability").text = GetElementTaggedValue(element,"Traceability");

        return xmlRow;
}

//helper function to create an empty xml document 
function CreateXmlDOC()
{
    var xmlDOM;
    try
    {
           xmlDOM = new ActiveXObject( "MSXML2.DOMDocument.4.0" );
    }
    catch(e)
    {
           xmlDOM = new ActiveXObject( "MSXML2.DOMDocument.6.0" );
    }

    xmlDOM.createProcessingInstruction("xml","version=\"1.0\"");
    xmlDOM.validateOnParse = false;
    xmlDOM.async = false;

    return xmlDOM;
}

//helper function to create the beginning of an xml document 
//suitable to render the results of a search:
function CreateXmlReport(xmlDOC){
    var xmlRoot = AppendXmlChild(xmlDOC,"EADATA");
    var xmlDataSet = AppendXmlChild(xmlRoot,"Dataset_0");
    var xmlData = AppendXmlChild(xmlDataSet,"Data");

    return xmlData;
}

//helper function to attach a new child xml element to a parent xml element
function AppendXmlChild(xmlParent, xmlElementName, isCDATA){
    var xmlDocument = xmlParent.ownerDocument;
    if (!xmlDocument){xmlDocument = xmlParent}
    var child = xmlDocument.createElement(xmlElementName);
    xmlParent.appendChild(child);
    return child;
}

//Gets an Element's tag. Eats exception if Tag does not exist.
function GetElementTaggedValue(element, tagName){
    var tag;
    try {
        tag = element.TaggedValues.GetByName(tagName);
    }
    catch (e) {
    }
    if (!tag){return;}
    var result = tag.Value;
    return result;
}


function ConvertPackageIdToBranchId(packageId){
    var package = Repository.GetPackageByID(objectId);
    if (!package){return;}

    var packages = [package];
    packages.concat(ConvertPackageToBranch(package));

    var result=[];
    for(var i=0;i<packages.length;i++){
        result.push(packages[i].PackageID);
    }
    return result;
}
function ConvertPackageToBranch(package){
    var result = [];

    for (var i=0;i<package.Packages.Count();i++){
        var childPackage = package.Packages.GetAt(i);
        result.push(childPackage);
        result.concat(ConvertPackageToBranch(childPackage));
    }
    return result;
}


//devTest();