You can solve that with without any loops by using xPath:

To make things easier for me, I skip the Get items and save the data in 2 Compose actions:
Risks:
Spoiler (Highlight to read)
[
{
"Name": "PN0",
"Issue": "PR0"
},
{
"Name": "PN1",
"Issue": "PR1"
},
{
"Name": "PN1",
"Issue": "PR10"
},
{
"Name": "PN1",
"Issue": "PR11"
},
{
"Name": "PN2",
"Issue": "PR2"
},
{
"Name": "PN3",
"Issue": "PI3"
}
]
[
{
"Name": "PN0",
"Issue": "PR0"
},
{
"Name": "PN1",
"Issue": "PR1"
},
{
"Name": "PN1",
"Issue": "PR10"
},
{
"Name": "PN1",
"Issue": "PR11"
},
{
"Name": "PN2",
"Issue": "PR2"
},
{
"Name": "PN3",
"Issue": "PI3"
}
]
Issues:
Spoiler (Highlight to read)
[
{
"Name": "PN0",
"Issue": "PI0"
},
{
"Name": "PN1",
"Issue": "PI1"
},
{
"Name": "PN2",
"Issue": "PI2"
},
{
"Name": "PN3",
"Issue": "PI3"
},
{
"Name": "PN3",
"Issue": "PI30"
},
{
"Name": "PN4",
"Issue": "PI4"
}
]
[
{
"Name": "PN0",
"Issue": "PI0"
},
{
"Name": "PN1",
"Issue": "PI1"
},
{
"Name": "PN2",
"Issue": "PI2"
},
{
"Name": "PN3",
"Issue": "PI3"
},
{
"Name": "PN3",
"Issue": "PI30"
},
{
"Name": "PN4",
"Issue": "PI4"
}
]
The Select action takes all names from Risks and Issues
union(
xpath(
xml(json(concat('{"root":{"name":',outputs('Risks'),'}}'))),
'//Name/text()'
),
xpath(
xml(json(concat('{"root":{"name":',outputs('Issues'),'}}'))),
'//Name/text()'
)
)
and maps this as following:
Name:
item()
Risks:
join(
xpath(
xml(json(concat('{"root":{"name":',outputs('Risks'),'}}'))),
concat('//name[Name="', item(), '"]/Issue/text()')
),
decodeUriComponent('%0A')
)
Issues:
join(
xpath(
xml(json(concat('{"root":{"name":',outputs('Issues'),'}}'))),
concat('//name[Name="', item(), '"]/Issue/text()')
),
decodeUriComponent('%0A')
)
Since there are multiple risks and issues per name, they are joined with a line break.
The Create HTML table simply takes the body of the Select:
@{body('Select')}
The final table looks a bit awkward, but you can fix this with some styles (but this is another topic 😉)
