I have an Azure Logic app and want to access a blob storage via the http-connector. (I know that there are dedicated blob-connectors but I can't use them).
The result of my http call to get a list of files looks like this:
{
"body": {
"$content": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48.............",
"$content-type": "application/xml"
},
"headers": {
"Content-Length": "2198313",
"Content-Type": "application/xml",
"Date": "Wed, 11 Oct 2023 14:50:46 GMT",
"Server": "Windows-Azure-Blob/1.0,Microsoft-HTTPAPI/2.0",
"Transfer-Encoding": "chunked",
"x-ms-client-request-id": "XXXXXXXX-ca8b-4876-8369-eff99d9fe0c3",
"x-ms-request-id": "XXXXXXX-801e-005d-2d52-fc4b85000000",
"x-ms-version": "2020-04-08"
},
"statusCode": 200
}
Inside the content field is a base64 encoded XML file which looks like this.
<?xml version=\"1.0\" encoding=\"utf-8\"?>
<EnumerationResults ServiceEndpoint=\"https://myblob.blob.core.windows.net/\" ContainerName=\"landing\">
<Blobs>
<Blob>
<Name>log.txt</Name>
<Properties>
<Creation-Time>Wed, 10 Aug 2022 11:13:23 GMT</Creation-Time>
<Last-Modified>Wed, 10 Aug 2022 11:13:23 GMT</Last-Modified>
<Etag>0x8DA7AC15724FC84</Etag>
<Content-Length>0</Content-Length>
<Content-Type>application/octet-stream</Content-Type>
<Content-Encoding/>
<Content-Language/>
<Content-CRC64>AAAAAAAAAAA=</Content-CRC64>
<Content-MD5/>
<Cache-Control/>
<Content-Disposition/>
<BlobType>BlockBlob</BlobType>
<AccessTier>Hot</AccessTier>
<AccessTierInferred>true</AccessTierInferred>
<LeaseStatus>unlocked</LeaseStatus>
<LeaseState>available</LeaseState>
<ServerEncrypted>true</ServerEncrypted>
</Properties>
<OrMetadata/>
</Blob>
<Blob>
<Name>test.txt</Name>
<Properties>
<Creation-Time>Fri, 08 Sep 2023 09:26:20 GMT</Creation-Time>
<Last-Modified>Fri, 08 Sep 2023 09:26:20 GMT</Last-Modified>
<Etag>0x8DBB04DA9A2ED71</Etag>
<Content-Length>0</Content-Length>
<Content-Type>application/octet-stream</Content-Type>
<Content-Encoding/>
<Content-Language/>
<Content-CRC64>AAAAAAAAAAA=</Content-CRC64>
<Content-MD5/>
<Cache-Control/>
<Content-Disposition/>
<BlobType>BlockBlob</BlobType>
<AccessTier>Hot</AccessTier>
<AccessTierInferred>true</AccessTierInferred>
<LeaseStatus>unlocked</LeaseStatus>
<LeaseState>available</LeaseState>
<ServerEncrypted>true</ServerEncrypted>
</Properties>
<OrMetadata/>
</Blob>
....
...
..
.
</Blobs>
</EnumerationResults>
Now I want to iterate over every blob to gather the name and Last-Modified. Therefore I set up two nested for-each loops with an xpath expression.
If I take a look at the run history of my workflow the result is failed and it seems that my for-each loop is never entered.
My first for-each expression looks like this:
xpath(xml(variables('Body')),'EnumerationResults/Blobs')
The second one:
xpath(xml(items('For_each')),'Blobs/Blob')
What could be the reason, why my loops are not working?
I am able to get the blob name and Last-Modified date in the following way-
Workflow-
Code-
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"For_each": {
"actions": {
"For_each_1": {
"actions": {
"Set_variable": {
"inputs": {
"name": "Name",
"value": "@{xpath(xml(items('For_each_1')),'Blob/Name/text()')[0]}"
},
"type": "SetVariable"
},
"Set_variable_1": {
"inputs": {
"name": "Last-Modified",
"value": "@{xpath(xml(items('For_each_1')),'Blob/Properties/Last-Modified/text()')[0]}"
},
"runAfter": {
"Set_variable": [
"SUCCEEDED"
]
},
"type": "SetVariable"
}
},
"foreach": "@xpath(xml(items('For_each')),'Blobs/Blob')",
"type": "Foreach"
}
},
"foreach": "@xpath(xml(triggerbody()),'EnumerationResults/Blobs')",
"runAfter": {
"Last-Modified": [
"SUCCEEDED"
]
},
"type": "Foreach"
},
"Last-Modified": {
"inputs": {
"variables": [
{
"name": "Last-Modified",
"type": "string"
}
]
},
"runAfter": {
"Name": [
"SUCCEEDED"
]
},
"type": "InitializeVariable"
},
"Name": {
"inputs": {
"variables": [
{
"name": "Name",
"type": "string"
}
]
},
"runAfter": { },
"type": "InitializeVariable"
}
},
"contentVersion": "1.0.0.0",
"outputs": { },
"triggers": {
"HTTP": {
"inputs": {
"method": "GET",
"uri": "https://afreenstorage12.blob.core.windows.net/demo?restype=container&comp=list&sv=2022-11-02&ss=bfqt&srt=sco&sp=yyyyy&se=2023-10-26T20:08:12Z&st=2023-10-26T12:08:12Z&spr=https&sig=***********"
},
"recurrence": {
"frequency": "Minute",
"interval": 3
},
"type": "Http"
}
}
},
"kind": "Stateful"
}
First For_each loop-
xpath(xml(triggerbody()),'EnumerationResults/Blobs')
Second For_each loop-
xpath(xml(items('For_each')),'Blobs/Blob')
Output-
You can follow my approach to get the blob name and Last-Modified date.