Last active
December 3, 2024 13:31
-
-
Save jkowalleck/a0f874ee0a8af9a56a0e887631fc53d1 to your computer and use it in GitHub Desktop.
CycloneDX dependency grapth to mermaid diagramm
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<stylesheet version="2.0" | |
xmlns="http://www.w3.org/1999/XSL/Transform" | |
xmlns:xs="http://www.w3.org/2001/XMLSchema" | |
xmlns:fn="http://www.w3.org/2005/xpath-functions" | |
xmlns:my="http://gist.github.com/jkowalleck/a0f874ee0a8af9a56a0e887631fc53d1" | |
> | |
<!-- | |
@author: Jan Kowalleck | |
@license: (MIT OR Apache-2.0) | |
@description: generate mermaid charts from the dependency graph in CycloneDX XML documents. | |
--> | |
<output method="text" indent="no" media-type="text/vnd.mermaid"/> | |
<param name="graphDirection" select="'TD'"> | |
<!-- see https://mermaid.js.org/syntax/flowchart.html#direction --> | |
</param> | |
<variable name="bomNS" select="fn:namespace-uri(/*:bom[fn:starts-with(fn:namespace-uri(), 'http://cyclonedx.org/schema/bom/1.')])"/> | |
<function name="my:isNS" as="xs:boolean"> | |
<param name="c"/> | |
<sequence select="fn:namespace-uri($c) = $bomNS"/> | |
</function> | |
<template match="/"> | |
<for-each select="*:bom[my:isNS(.)]"> | |
<text>graph </text> | |
<value-of select="$graphDirection"/> | |
<text>; </text> | |
<for-each select="*:dependencies[my:isNS(.)]/*:dependency[my:isNS(.)]"> | |
<call-template name="renderDependency"/> | |
</for-each> | |
</for-each> | |
</template> | |
<template name="renderDependency"> | |
<for-each select="*:dependency[my:isNS(.)]"> | |
<value-of select="my:mmRelation(../@ref, @ref, 'depends')"/> | |
<call-template name="renderDependency"> | |
<!-- the xml allows nested dependencies -> recursion is needed --> | |
</call-template> | |
</for-each> | |
<for-each select="*:provides[my:isNS(.)]"> | |
<value-of select="my:mmRelation(../@ref, @ref, 'provides')"/> | |
</for-each> | |
</template> | |
<function name="my:mmEscapeNode" as="xs:string"> | |
<!-- escape chars that mermaid does not allow for node names --> | |
<param name="i" as="xs:string"/> | |
<sequence select="fn:translate($i, '@:=[]{}() "><', '_____________')"/> | |
</function> | |
<function name="my:mmRelation" as="xs:string"> | |
<param name="a" as="xs:string"/> | |
<param name="b" as="xs:string"/> | |
<param name="r" as="xs:string"/> | |
<xs:sequence> | |
<text> </text> | |
<value-of select="my:mmEscapeNode($a)"/> | |
<text>["</text> | |
<value-of select="$a"/> | |
<text>"] -- </text> | |
<value-of select="$r"/> | |
<text> --> </text> | |
<value-of select="my:mmEscapeNode($b)"/> | |
<text>["</text> | |
<value-of select="$b"/> | |
<text>"] </text> | |
</xs:sequence> | |
</function> | |
</stylesheet> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
call like here: https://gist.github.com/jkowalleck/a0f874ee0a8af9a56a0e887631fc53d1?permalink_comment_id=5097436#gistcomment-5097436
example results based on https://github.com/CycloneDX/cyclonedx-php-composer/blob/704cf28ade153274d94892ebeb3cb18e8422b5d0/demo/laravel-7.12.0/results/bom.1.6.xml
rendered: https://mermaid.live/view#pako:eNrNnM1zqzYQwP-VDOcAxrFN7M701GN7aW9telCEbKsWEiMJv5DM-9-7fJja5sM2SPS9N5MQdq39Ia12VxLJl4NFRJyNs5Mo2T_9-vtPb_wJ_iEVv659pRE-uFhI5QbeizfzZn-9OV2iN-fvJ9d9ikhCeKTg8ucnlcVbwTN_r3XibkXKI6Sp4O7SW3jBqmjtlgq0ao3oQCQnrJPmSlyTkF3KKFI-iRFl7hExCsxCunMv8ObLop1bKi1kkcBaUk58Rj6IhEeY5w8BbbULLNOcOiIRLNtSxlzKNXyJeG4_rPr9tlJNuZUp1Rgd4CmQREfo1mqgZl7Z8_0KLYTD_MEWjUlPt0w30Ot36ecnI7mKX166K2_pvRYNdMpaWM50EyliqkhOvgSvvmrpWmqVRMkQ7KwrB-qQGCcwPcuGPNE1E4hLR4iJUmhHCrcKika6REbtS8REmuwp8XdEI8b2BEUEvDufwWVAvKFR01STw99KFJNvQh7c0Hs5zaFuYV9spnzLCC5j56mlbqENEol2gseIa8QPPpYQP8hHImE88lCSZ4ZyqO7Ss8BnJhuZpmIE7VLiYxHHeaeAcgCaYdlQl8wex5ZlKlOaxGAK_s_OOZoyCxzwpIKJnV99h65_reZph8QCAyfqXWgfI_leeOTqlL3bBRYIREKVj5lQqSQQPFZVeGm7bcF6HkyxgPkJoUOWg10H2cZ9S_YVjRNIUBjh_XWcbxNZoAAdRTI_TWnkLuqSt-WuBdvqG93qPAgReNz_rt1VXUje0LDBVCV78AAloP9bqrRrkUUKIiUE5j3iUf7UhcHlBUu7gkWiLeXRyVJwgXIlschgosa3RDWwtjdPE9O41Xkv7lu0XxfLyT4JX3rL6UsNm0xSYCjA2pz3WmSRQopUU75rm83XIosURyTdKI2T04xdXIC0SC2waPqPOhJ5EBnhPobe1wLWVgzyrqt0xmDlOYfcU3bR3boWOI8sxVAvg59GQhN-hJR4SlBdIhsU4pDCpJEavUPyQQpTWlTKpSP3SBssp02L0Avm1XN0iVo4tjQiTIBr5JPmI4MnXlR7Bx0S0_ZH786YpBm6E2GSYbiP2aCACAZpDqZjWBWT7YKG9fs_16ykIYDDom3vzvLgva5q6OubBi0aiKIDV6IdK9oiressIW5ENMFFzRMUmey8xT6tmmzI2rRtbZNr5OCLeklzdqe29vgq9GbFEb-rfD9o11t0NJRsEkF6eJ3dqoHONCywaIm4YmfF8KWrtolrivvnV2OPgR4ozrOjmyCpYB4UdU2ZLTplBuyOWcWNtzo8KlTrbiwYq6fnvOqvTtm9Hhjc9MCg6YGP7A9cU7xLig9-jHTea-vqo82bRmwN7bnxlhs9iYsI29fXlxp2KAbHHBO7MjZ3pW3wNY94IDwc-w-BLjQmpht3SjUJ48gsPCyCd1HBPUlwmd7yvV2JsM5XjKdcdJeeJbYfs8fG79_Y4xkY14zyQMFypJj0elOnji2m0jNaNpauJE37SrmKVIenLdtjrfJJRmv4DvjwNYl52-Mrw9rkkXDtRlQlSON9pbm-pOpQmTw-2mFtfKQP-LbyRNQGZ4Tx52-bKY0PFpsE9bTpEjdoHzkvmtY7TZCZG9VxZ1rT9pwdVtN1kGVKMyP-8Hnh-Kxmxu4EHmaMcewpuiWqUXnGJpmJ83U7ZOP3WCxzjV4t2eMaF63ufZ9g2jgxlsrYjoppHkM50BjPaP8Z39P3jSEXMkaMfpa_qNFvoEX3_-DOI8L8ZsyY9zA-9F6L_bF-7A2XaSOGGTZzfTV2H8nMW622aOyO5SP7XfYrCqM0RSApfiWQxOR2yGloTkBnOtIaJTSUP40yjY4Vw87wp52TZhlNj6cluh9sZM_V-0a2V6_BOGTveqpxtcI2eFRtvdfa-ZbLwNObknbY262NumOfiCT3JL--Ovvtwx6pYQ5zeR1nmAlOog-_vsoHHGZKnIj8faWIxAK-HN0YKU0kNP3oR3reonzsXUzn2YkJpFgaORvnK-cHz8oLgjdnA5cRkoc3541_Bz2UavFHxrGz0TIlzw5Uvbu9s9kipuCnNImQJr9QBBVFfFIhEQXP-a38OwXFnyt4dhLE_xSiVoEfnc2X8-FswhU47CoIw3X4ugyWq_mzkzmbubcKZ8HLbBYsFsF6uVyG35-dz6KB4Pu_B1bYBg