I'm trying to get a list of reviews from an api.
This gives me a JSON with nested properties.
I manage to get almost all the data I need except from the nested array ["value"]["answers"]["value"] because sometimes the array ["answers"] has one item (with "id" being either "goods", "delivery" or "service"), or 2 or all 3 of them.
So I can't use the index to get what I want.
I need to be able to check the "id" and from that append the "value" to my array.
Is there a way to write an expression that checks the "id" and from then on writes the "value" in my array ?
JSON :
...
"surveyData": [
{
"questionRef": "q1",
"type": "CORE_STAR_RATING",
"properties": {
"title": "How do you evaluate ...?"
},
"value": {
"stars": 5,
"notAnswered": false
},
"userDefinedId": "q1"
},
"userDefinedId": "q2-good"
},
{
"questionRef": "q3",
"type": "DIMENSIONS",
"properties": {
"title": "How do you evaluate on those criterias ?"
},
**"value": {
"answers": [
{
"id": "delivery",
"value": 4,
"userDefinedId": "delivery",
"name": "Delivery",
"firstLabel": "Nul",
"lastLabel": "Good"
},
{
"id": "goods",
"value": 5,
"userDefinedId": "goods",
"name": "Goods",
"firstLabel": "Nul",
"lastLabel": "Good"
},
{
"id": "service",
"value": 5,
"userDefinedId": "service",
"name": "Service",
"firstLabel": "Nul",
"lastLabel": "Good"
}
]**
},
"userDefinedId": "q3-group"
}
]
...
My array so far :
"value": {
"Event": "#items('For_each-Service')?['event']?['type']",
"Delivery": "", <= ??
"Goods": "", <= ??
"Service": "#items('For_each-Service')?['surveyData'][2]?['value']?['answers'][2]?['value']", <= doesn't work
"comment": "#items('For_each-Service')?['reply']?['comment']",
"order date": "#items('For_each-Service')?['transaction']?['date']",
"date": "#items('For_each-Service')?['reply']?['createdAt']",
"email": "#items('For_each-Service')?['customer']?['email']",
"id review": "#items('For_each-Service')?['event']?['id']",
"name client": "#items('For_each-Service')?['customer']?['fullName']",
"status": "#items('For_each-Service')?['state']",
"title": "#items('For_each-Service')?['title']"
}
Thank you
There are a couple of ways to skin this cat, some more efficient than others.
Personally, I would take the following approach.
I created a flow where, basically, the first thing it does is initialise a variable that contains your Answers array as the data ...
The next step is to initialize another variable that stores that array as XML ...
This is the expression contained within ...
xml(json(concat('{ "root": { "answer": ', variables('Answers Array'), '}}')))
In the next step, I'm basically doing what you're doing by constructing an object, only this time, the selection for the values are a little more complex, this is the definition of the body ...
{
"Delivery": #{first(xpath(xml(variables('XML')), '//id[contains(text(), "delivery")]/parent::answer/value/text()'))},
"Goods": #{first(xpath(xml(variables('XML')), '//id[contains(text(), "goods")]/parent::answer/value/text()'))},
"Service": #{first(xpath(xml(variables('XML')), '//id[contains(text(), "service")]/parent::answer/value/text()'))}
}
Using the xpath approach for querying the dataset can cut down the amount of steps you need to take to get the desired result.
If an element is missing, it will simply come back as null ...
Below is one of the workarounds to achieve your requirement. Firstly, I have initialised 3 variables for Delivery, Goods and Service Counts.
Then used Parse_JSON to extract the inner values of the JSON provided.
In the next step I'm trying to iterate through Id's using Switch action with body('Parse_JSON')?['value']?['answers']?[iterationIndexes('Until')]?['id'] expression and set the variables using below expression inside an until loop.
body('Parse_JSON')?['value']?['answers']?[iterationIndexes('Until')]?['value']
and finally you can add in your array like below
RESULTS:
You can use below code view to reproduce in your logic app
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Compose": {
"inputs": {
"value": {
"answers": [
{
"firstLabel": "Nul",
"id": "goods",
"lastLabel": "Good",
"name": "Goods",
"userDefinedId": "goods",
"value": 4
},
{
"firstLabel": "Nul",
"id": "service",
"lastLabel": "Good",
"name": "Service",
"userDefinedId": "service",
"value": 5
}
]
}
},
"runAfter": {
"Initialize_variable_Service_Count": [
"Succeeded"
]
},
"type": "Compose"
},
"Compose_2": {
"inputs": " \"value\": {\n \"Event\": \"#items('For_each-Service')?['event']?['type']\",\n \"Delivery\": \"#{variables('Delivery Count')}\", \n \"Goods\": \"#{variables('Goods Count')}\", \n \"Service\": \"#{variables('Service Count')}\"\n }",
"runAfter": {
"Until": [
"Succeeded"
]
},
"type": "Compose"
},
"Initialize_variable": {
"inputs": {
"variables": [
{
"name": "i",
"type": "integer",
"value": 0
}
]
},
"runAfter": {},
"type": "InitializeVariable"
},
"Initialize_variable_Delivery_count": {
"inputs": {
"variables": [
{
"name": "Delivery Count",
"type": "integer"
}
]
},
"runAfter": {
"Initialize_variable": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Initialize_variable_Goods_Count": {
"inputs": {
"variables": [
{
"name": "Goods Count",
"type": "integer"
}
]
},
"runAfter": {
"Initialize_variable_Delivery_count": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Initialize_variable_Service_Count": {
"inputs": {
"variables": [
{
"name": "Service Count",
"type": "integer"
}
]
},
"runAfter": {
"Initialize_variable_Goods_Count": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Parse_JSON": {
"inputs": {
"content": "#outputs('Compose')",
"schema": {
"properties": {
"value": {
"properties": {
"answers": {
"items": {
"properties": {
"firstLabel": {
"type": "string"
},
"id": {
"type": "string"
},
"lastLabel": {
"type": "string"
},
"name": {
"type": "string"
},
"userDefinedId": {
"type": "string"
},
"value": {
"type": "integer"
}
},
"required": [],
"type": "object"
},
"type": "array"
}
},
"type": "object"
}
},
"type": "object"
}
},
"runAfter": {
"Compose": [
"Succeeded"
]
},
"type": "ParseJson"
},
"Until": {
"actions": {
"Increment_variable": {
"inputs": {
"name": "i",
"value": 1
},
"runAfter": {
"Switch": [
"Succeeded"
]
},
"type": "IncrementVariable"
},
"Switch": {
"cases": {
"Case_Delivery": {
"actions": {
"Set_variable_Delivery_Count": {
"inputs": {
"name": "Delivery Count",
"value": "#body('Parse_JSON')?['value']?['answers']?[iterationIndexes('Until')]?['value']"
},
"runAfter": {},
"type": "SetVariable"
}
},
"case": "delivery"
},
"Case_Goods": {
"actions": {
"Set_variable_Goods_Count": {
"inputs": {
"name": "Goods Count",
"value": "#body('Parse_JSON')?['value']?['answers']?[iterationIndexes('Until')]?['value']"
},
"runAfter": {},
"type": "SetVariable"
}
},
"case": "goods"
},
"Case_Service": {
"actions": {
"Set_variable_Service_Count": {
"inputs": {
"name": "Service Count",
"value": "#body('Parse_JSON')?['value']?['answers']?[iterationIndexes('Until')]?['value']"
},
"runAfter": {},
"type": "SetVariable"
}
},
"case": "service"
}
},
"default": {
"actions": {}
},
"expression": "#body('Parse_JSON')?['value']?['answers']?[iterationIndexes('Until')]?['id']",
"runAfter": {},
"type": "Switch"
}
},
"expression": "#equals(variables('i'), length(body('Parse_JSON')?['value']?['answers']))",
"limit": {
"count": 10,
"timeout": "PT1H"
},
"runAfter": {
"Parse_JSON": [
"Succeeded"
]
},
"type": "Until"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {},
"triggers": {
"manual": {
"inputs": {
"schema": {}
},
"kind": "Http",
"type": "Request"
}
}
},
"parameters": {}
}
Related
I have been struggling with this for a long time to construct an output where my [key] is separated from my array value, please help to share your expertise.
Below is the response, i have received from Azure Alert and I'm looking forward to create an output (refer Expected Output image).
{
"tables": [
{
"columns": [
{
"name": "task",
"type": "string"
},
{
"name": "environment",
"type": "string"
},
{
"name": "workspace",
"type": "string"
}
],
"name": "PrimaryResult",
"rows": [
[
"job_name_1",
"PRODUCTION",
"WORKSPACE-1",
],
[
"job_name_2",
"TEST",
"WORKSPACE-2",
]
]
}
]
}
Inside Logic App. I have parsed the json and used a lot of for each loop variations but, every single time, i get stuck in traversing the rows as its a 2d array. Even though, i traverse them, i cannot associate them with columns. Any alternative approaches will be appreciated ?
Input
Expected Output
[
{
"task": "job_name_1",
"environment": "PRODUCTION",
"workspace" : "WORKSPACE-1"
},
{
"task": "job_name_2",
"environment": "TEST",
"workspace" : "WORKSPACE-2"
}
]
I'd be lying if I said this was straight forward but you can load the below definition into your tenant and see a working version.
Note: I made the assumption that you only ever have one table in your top level array given that's what you provided in your question.
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"For_Each_Row": {
"actions": {
"Append_To_Transformed_Array": {
"inputs": {
"name": "Transformed Array",
"value": "#variables('Row Object')"
},
"runAfter": {
"For_Each_Column": [
"Succeeded"
]
},
"type": "AppendToArrayVariable"
},
"For_Each_Column": {
"actions": {
"Add_Property_To_Temp_Row_Object": {
"inputs": {
"name": "Temp Row Object",
"value": "#addProperty(variables('Row Object'), variables('Columns')?[variables('Column Index')]['name'], items('For_Each_Column'))"
},
"runAfter": {},
"type": "SetVariable"
},
"Increment_Column_Index": {
"inputs": {
"name": "Column Index",
"value": 1
},
"runAfter": {
"Set_Row_Object_From_Temp_Row_Object": [
"Succeeded"
]
},
"type": "IncrementVariable"
},
"Set_Row_Object_From_Temp_Row_Object": {
"inputs": {
"name": "Row Object",
"value": "#variables('Temp Row Object')"
},
"runAfter": {
"Add_Property_To_Temp_Row_Object": [
"Succeeded"
]
},
"type": "SetVariable"
}
},
"foreach": "#item()",
"runAfter": {
"Reset_Column_Index": [
"Succeeded"
]
},
"type": "Foreach"
},
"Reset_Column_Index": {
"inputs": {
"name": "Column Index",
"value": 0
},
"runAfter": {
"Reset_Temp_Row_Object": [
"Succeeded"
]
},
"type": "SetVariable"
},
"Reset_Row_Object": {
"inputs": {
"name": "Row Object",
"value": {}
},
"runAfter": {},
"type": "SetVariable"
},
"Reset_Temp_Row_Object": {
"inputs": {
"name": "Temp Row Object",
"value": {}
},
"runAfter": {
"Reset_Row_Object": [
"Succeeded"
]
},
"type": "SetVariable"
}
},
"foreach": "#variables('Rows')",
"runAfter": {
"Initialize_Column_Index": [
"Succeeded"
]
},
"runtimeConfiguration": {
"concurrency": {
"repetitions": 1
}
},
"type": "Foreach"
},
"Initialize_Column_Index": {
"inputs": {
"variables": [
{
"name": "Column Index",
"type": "integer"
}
]
},
"runAfter": {
"Initialize_Temp_Row_Object": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Initialize_Columns": {
"inputs": {
"variables": [
{
"name": "Columns",
"type": "array",
"value": "#variables('Data')?['tables'][0]['columns']"
}
]
},
"runAfter": {
"Initialize_Data": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Initialize_Data": {
"inputs": {
"variables": [
{
"name": "Data",
"type": "object",
"value": {
"tables": [
{
"columns": [
{
"name": "task",
"type": "string"
},
{
"name": "environment",
"type": "string"
},
{
"name": "workspace",
"type": "string"
}
],
"name": "PrimaryResult",
"rows": [
[
"job_name_1",
"PRODUCTION",
"WORKSPACE-1"
],
[
"job_name_2",
"TEST",
"WORKSPACE-2"
]
]
}
]
}
}
]
},
"runAfter": {},
"type": "InitializeVariable"
},
"Initialize_Row_Object": {
"inputs": {
"variables": [
{
"name": "Row Object",
"type": "object"
}
]
},
"runAfter": {
"Initialize_Transformed_Array": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Initialize_Rows": {
"inputs": {
"variables": [
{
"name": "Rows",
"type": "array",
"value": "#variables('Data')?['tables'][0]['rows']"
}
]
},
"runAfter": {
"Initialize_Columns": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Initialize_Temp_Row_Object": {
"inputs": {
"variables": [
{
"name": "Temp Row Object",
"type": "object",
"value": {}
}
]
},
"runAfter": {
"Initialize_Row_Object": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Initialize_Transformed_Array": {
"inputs": {
"variables": [
{
"name": "Transformed Array",
"type": "array"
}
]
},
"runAfter": {
"Initialize_Rows": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Result": {
"inputs": "#variables('Transformed Array')",
"runAfter": {
"For_Each_Row": [
"Succeeded"
]
},
"type": "Compose"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {},
"triggers": {
"manual": {
"inputs": {
"method": "GET",
"schema": {}
},
"kind": "Http",
"type": "Request"
}
}
},
"parameters": {}
}
The main challenges I see with having to do this are ...
The lack of ability to self reference. Because of that, I had to use a Row Object in conjunction with a Temp Row Object when adding the property each time.
The amount of nesting is a little hard to follow but it works.
Performance will be a real burden if you have a lot of rows.
One thing to note is the outer For Each action needs to have the concurrency set to 1, if it's not, you'll run into problems.
This is the end result as you were wanting ...
In the process of moving over to Azure ecosystem fully, I'm trying to recreate a mail merge via Logic apps.
The basic idea is we get the data output via stored proc with the test data similar to:
create table dbo.People (
Name nvarchar(255),
Local char(1) null,
Earned float null,
Email nvarchar(255) null
);
insert into dbo.People values ('Bob','N',20,'Bob#Fakemail.com');
insert into dbo.People values ('Bob','Y',28,'Bob#Fakemail.com');
insert into dbo.People values ('Jess','N',25,'Jess#Fakemail.com');
insert into dbo.People values ('Jess','Y',39,'Jess#Fakemail.com');
Is this doable in logic app? Trying to avoid paying for any addons.
Tried few tests and it seems to work fine with one line per name/person. Once it brings more than one line it duplicates the emails. Is there a way to combine them all?
-- for for one line outputs (from SQL) of course it will duplicate if there is more than one. Though, not sure how to combine or process in bulk.
What would be the most efficient way of doing this?
Appreciate tips and tricks!
After reproducing from my end, I could be able to achieve this by using 2 until loops where I have defined the condition to check for distinct emails and send the required details using outlook connector.
Alternatively, you can even use foreach loop instead of until if you use a similar logic. Below is the flow of my logic app.
Initially, I have used 2 Queries. One to get the total table and other to get only the distinct emails.
In first Until loop, I have Set the Email to read the distinct emails
In the second until loop, I have used condition and if it is true, the required details will be appended to the array using the below expression.
{
"Name":"#{body('Execute_a_SQL_query_(V2)')?['resultsets']?['Table1'][variables('Loop2')]['Name']}",
"Local":"#{body('Execute_a_SQL_query_(V2)')?['resultsets']?['Table1'][variables('Loop2')]['Local']}",
"Earned":"#{body('Execute_a_SQL_query_(V2)')?['resultsets']?['Table1'][variables('Loop2')]['Earned']}",
"Email":"#{body('Execute_a_SQL_query_(V2)')?['resultsets']?['Table1'][variables('Loop2')]['Email']}"
}
Finally, I'm sending the updated variable through mail
Below is the complete Code view of my Logic App
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Execute_a_SQL_query_(V2)": {
"inputs": {
"body": {
"query": "SELECT * FROM dbo.People"
},
"host": {
"connection": {
"name": "#parameters('$connections')['sql']['connectionId']"
}
},
"method": "post",
"path": "/v2/datasets/#{encodeURIComponent(encodeURIComponent('default'))},#{encodeURIComponent(encodeURIComponent('default'))}/query/sql"
},
"runAfter": {},
"type": "ApiConnection"
},
"Execute_a_SQL_query_(V2)_-_Distinct_Emails": {
"inputs": {
"body": {
"query": "SELECT DISTINCT Email FROM dbo.People"
},
"host": {
"connection": {
"name": "#parameters('$connections')['sql']['connectionId']"
}
},
"method": "post",
"path": "/v2/datasets/#{encodeURIComponent(encodeURIComponent('default'))},#{encodeURIComponent(encodeURIComponent('default'))}/query/sql"
},
"runAfter": {
"Execute_a_SQL_query_(V2)": [
"Succeeded"
]
},
"type": "ApiConnection"
},
"Initialize_variable_-_Details": {
"inputs": {
"variables": [
{
"name": "Details",
"type": "array"
}
]
},
"runAfter": {
"Initialize_variable_-_Email": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Initialize_variable_-_Email": {
"inputs": {
"variables": [
{
"name": "Email",
"type": "string"
}
]
},
"runAfter": {
"Initialize_variable_-_Loop2": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Initialize_variable_-_Loop1": {
"inputs": {
"variables": [
{
"name": "Loop1",
"type": "integer",
"value": 0
}
]
},
"runAfter": {
"Execute_a_SQL_query_(V2)_-_Distinct_Emails": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Initialize_variable_-_Loop2": {
"inputs": {
"variables": [
{
"name": "Loop2",
"type": "integer",
"value": 0
}
]
},
"runAfter": {
"Initialize_variable_-_Loop1": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Until_-_Loop1": {
"actions": {
"Compose": {
"inputs": "#variables('Details')",
"runAfter": {
"Increment_variable_-_Loop1": [
"Succeeded"
]
},
"type": "Compose"
},
"Increment_variable_-_Loop1": {
"inputs": {
"name": "Loop1",
"value": 1
},
"runAfter": {
"Until_-_Loop2": [
"Succeeded"
]
},
"type": "IncrementVariable"
},
"Set_variable_Details_to_null": {
"inputs": {
"name": "Details",
"value": "#null"
},
"runAfter": {
"Set_variable_Loop2_to_0": [
"Succeeded"
]
},
"type": "SetVariable"
},
"Set_variable_Distinct_Email": {
"inputs": {
"name": "Email",
"value": "#{body('Execute_a_SQL_query_(V2)_-_Distinct_Emails')?['resultsets']?['Table1'][variables('Loop1')]['Email']}"
},
"runAfter": {},
"type": "SetVariable"
},
"Set_variable_Loop2_to_0": {
"inputs": {
"name": "Loop2",
"value": 0
},
"runAfter": {
"Set_variable_Distinct_Email": [
"Succeeded"
]
},
"type": "SetVariable"
},
"Until_-_Loop2": {
"actions": {
"Condition": {
"actions": {
"Append_to_array_variable": {
"inputs": {
"name": "Details",
"value": {
"Earned": "#{body('Execute_a_SQL_query_(V2)')?['resultsets']?['Table1'][variables('Loop2')]['Earned']}",
"Email": "#{body('Execute_a_SQL_query_(V2)')?['resultsets']?['Table1'][variables('Loop2')]['Email']}",
"Local": "#{body('Execute_a_SQL_query_(V2)')?['resultsets']?['Table1'][variables('Loop2')]['Local']}",
"Name": "#{body('Execute_a_SQL_query_(V2)')?['resultsets']?['Table1'][variables('Loop2')]['Name']}"
}
},
"runAfter": {},
"type": "AppendToArrayVariable"
}
},
"expression": {
"and": [
{
"equals": [
"#variables('Email')",
"#body('Execute_a_SQL_query_(V2)')?['resultsets']?['Table1'][variables('Loop2')]['Email']"
]
}
]
},
"runAfter": {},
"type": "If"
},
"Increment_variable": {
"inputs": {
"name": "Loop2",
"value": 1
},
"runAfter": {
"Condition": [
"Succeeded"
]
},
"type": "IncrementVariable"
}
},
"expression": "#equals(variables('Loop2'), length(array(body('Execute_a_SQL_query_(V2)')?['resultsets']?['Table1'])))",
"limit": {
"count": 60,
"timeout": "PT1H"
},
"runAfter": {
"Set_variable_Details_to_null": [
"Succeeded"
]
},
"type": "Until"
}
},
"expression": "#equals(variables('Loop1'), length(array(body('Execute_a_SQL_query_(V2)_-_Distinct_Emails')?['resultsets']?['Table1'])))",
"limit": {
"count": 60,
"timeout": "PT1H"
},
"runAfter": {
"Initialize_variable_-_Details": [
"Succeeded"
]
},
"type": "Until"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {
"$connections": {
"defaultValue": {},
"type": "Object"
}
},
"triggers": {
"manual": {
"inputs": {
"schema": {}
},
"kind": "Http",
"type": "Request"
}
}
},
"parameters": {
"$connections": {
"value": {
"sql": {
"connectionId": "/subscriptions/<ID>/resourceGroups/<RG>/providers/Microsoft.Web/connections/sql",
"connectionName": "sql",
"id": "/subscriptions/<ID>/providers/Microsoft.Web/locations/westus2/managedApis/sql"
}
}
}
}
}
What I would like to do it if there is addOn array, I would like to append the word "xxx" to the end of the name.
Schema applied to message.
{
"properties": {
"appointment": {
"properties": {
"id": {
"type": "integer"
},
"lines": {
"items": {
"properties": {
"addOn": {
"items": {
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
},
"required": [
"id",
"name"
],
"type": "object"
},
"type": "array"
},
"id": {
"type": "integer"
},
"price": {
"type": "integer"
}
},
"required": [
"id",
"price"
],
"type": "object"
},
"type": "array"
}
},
"type": "object"
},
"messageId": {
"type": "string"
}
},
"type": "object"
}
Message 1
{
"messageId": "11",
"appointment": {
"id": 22,
"lines": [
{
"id": 33,
"price": 125.0,
"addOn": [
{
"id": 44,
"name": "test"
}
]
}
]
}
}
Message 2
{
"messageId": "11",
"appointment": {
"id": 22,
"lines": [
{
"id": 33,
"price": 125.0
}
]
}
}
Message 1 works fine but whenever I try and use length or Parse Array I get a message that addOn is null.
How can I put a proper Condition express to not get any errors or do nothing when there is no addOn array.
Logic App.
Message1 - Okay
Message2 - Error
Code View.
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"For_each": {
"actions": {
"For_each_2": {
"actions": {
"Condition_3": {
"actions": {},
"expression": {
"and": [
{
"equals": [
"#empty(items('For_each_2'))",
"True"
]
}
]
},
"runAfter": {},
"type": "If"
}
},
"foreach": "#items('For_each')['addOn']",
"runAfter": {},
"type": "Foreach"
}
},
"foreach": "#body('Parse_JSON')?['appointment']?['lines']",
"runAfter": {
"Parse_JSON": [
"Succeeded"
]
},
"type": "Foreach"
},
"Parse_JSON": {
"inputs": {
"content": "#triggerBody()",
"schema": {
"properties": {
"appointment": {
"properties": {
"id": {
"type": "integer"
},
"lines": {
"items": {
"properties": {
"addOn": {
"items": {
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
},
"required": [
"id",
"name"
],
"type": "object"
},
"type": "array"
},
"id": {
"type": "integer"
},
"price": {
"type": "integer"
}
},
"required": [
"id",
"price"
],
"type": "object"
},
"type": "array"
}
},
"type": "object"
},
"messageId": {
"type": "string"
}
},
"type": "object"
}
},
"runAfter": {},
"type": "ParseJson"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {},
"triggers": {
"manual": {
"inputs": {
"schema": {
"properties": {
"appointment": {
"properties": {
"id": {
"type": "integer"
},
"lines": {
"items": {
"properties": {
"addOn": {
"items": {
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
},
"required": [
"id",
"name"
],
"type": "object"
},
"type": "array"
},
"id": {
"type": "integer"
},
"price": {
"type": "integer"
}
},
"required": [
"id",
"price",
"addOn"
],
"type": "object"
},
"type": "array"
}
},
"type": "object"
},
"messageId": {
"type": "string"
}
},
"type": "object"
}
},
"kind": "Http",
"type": "Request"
}
}
},
"parameters": {}
}
Steve
I would like to append the word "xxx" to the end of the name.
For appending you can directly add while setting the "name" variable.
Alternatively, you can also use concat function as below.
concat(body('Parse_JSON')?['appointment']?['lines'][0]['addOn'][0]['name'],variables('xxx'))
where both cases would give the result as the following
How can I put a proper Condition express to not get any errors or do nothing when there is no addOn array.
You can do this in many ways where one of the workarounds would be using if the lines contain "addOn" or not.
"contains": ["#body('Parse_JSON')?['appointment']?['lines'][0]","addOn"]
MESSAGE1 RESULTS:
MESSAGE2 RESULTS:
You can reproduce the same in your logic app using the below codeview
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Compose": {
"inputs": "#variables('Message')",
"runAfter": {
"For_each": [
"Succeeded"
]
},
"type": "Compose"
},
"For_each": {
"actions": {
"Condition": {
"actions": {
"Set_variable": {
"inputs": {
"name": "Message",
"value": {
"appointment": {
"id": "#body('Parse_JSON')?['appointment']?['id']",
"lines": [
{
"addOn": "addOn is NULL",
"id": "#items('For_each')?['id']",
"price": "#items('For_each')?['price']"
}
]
},
"messageId": "#{body('Parse_JSON')?['messageId']}"
}
},
"runAfter": {},
"type": "SetVariable"
}
},
"else": {
"actions": {
"For_each_2": {
"actions": {
"Set_variable_2": {
"inputs": {
"name": "Message",
"value": {
"appointment": {
"id": "#body('Parse_JSON')?['appointment']?['id']",
"lines": [
{
"addOn": [
{
"id": "#items('For_each_2')?['id']",
"name": "#{concat(body('Parse_JSON')?['appointment']?['lines'][0]['addOn'][0]['name'],variables('xxx'))}"
}
],
"id": "#items('For_each')?['id']",
"price": "#items('For_each')?['price']"
}
]
},
"messageId": "#{body('Parse_JSON')?['messageId']}"
}
},
"runAfter": {},
"type": "SetVariable"
}
},
"foreach": "#items('For_each')['addOn']",
"runAfter": {},
"type": "Foreach"
}
}
},
"expression": {
"and": [
{
"not": {
"contains": [
"#body('Parse_JSON')?['appointment']?['lines'][0]",
"addOn"
]
}
}
]
},
"runAfter": {},
"type": "If"
}
},
"foreach": "#body('Parse_JSON')?['appointment']?['lines']",
"runAfter": {
"Initialize_variable_xxx": [
"Succeeded"
]
},
"type": "Foreach"
},
"Initialize_variable": {
"inputs": {
"variables": [
{
"name": "Message",
"type": "object"
}
]
},
"runAfter": {
"Parse_JSON": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Initialize_variable_xxx": {
"inputs": {
"variables": [
{
"name": "xxx",
"type": "string",
"value": "xxx"
}
]
},
"runAfter": {
"Initialize_variable": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Parse_JSON": {
"inputs": {
"content": "#triggerBody()",
"schema": {
"properties": {
"appointment": {
"properties": {
"id": {
"type": "integer"
},
"lines": {
"items": {
"properties": {
"addOn": {
"items": {
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
},
"required": [
"id",
"name"
],
"type": "object"
},
"type": "array"
},
"id": {
"type": "integer"
},
"price": {
"type": "integer"
}
},
"required": [
"id",
"price"
],
"type": "object"
},
"type": "array"
}
},
"type": "object"
},
"messageId": {
"type": "string"
}
},
"type": "object"
}
},
"runAfter": {},
"type": "ParseJson"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {},
"triggers": {
"manual": {
"inputs": {
"schema": {
"properties": {
"appointment": {
"properties": {
"id": {
"type": "integer"
},
"lines": {
"items": {
"properties": {
"addOn": {
"items": {
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
},
"required": [
"id",
"name"
],
"type": "object"
},
"type": "array"
},
"id": {
"type": "integer"
},
"price": {
"type": "integer"
}
},
"required": [
"id",
"price",
"addOn"
],
"type": "object"
},
"type": "array"
}
},
"type": "object"
},
"messageId": {
"type": "string"
}
},
"type": "object"
}
},
"kind": "Http",
"type": "Request"
}
}
},
"parameters": {}
}
I'm extracting a .txt into an array, line by line.
After doing that, I want to check for a match between a string variable and an element in the array(contains, does not have to be exact match), and return the index of said element.
Is there any solution to this?
I've both tried working with for-each loops and until-loops, but so far the app is iterating until it times out.
Considering this to be my .txt file
In the beginning, I'm just retrieving the text file and converting each line into an array.
Then I have Initialised 2 Variables and set Index to 0 and Status to false.
In the next step I'm using Until Connector, looping through the Array using outputs('Convert_txt_into_array')[variables('Index')] and check until the status is set to true.
So, Whether the status becomes true or false the index increments by 1 and loops through the Until connector. If the condition becomes true then the Index Variable is set to the current iteration by using iterationIndexes which gives us the current iteration and exits the Until block.
And Finally, I'm printing Index Variable in Compose connector for future usage [This step can be avoided].
RESULT - 1 :
RESULT - 2 :
Codeview of my logic app
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Compose": {
"inputs": "The #{variables('FindingString')} is at index : #{variables('Index')}",
"runAfter": {
"Until": [
"Succeeded"
]
},
"type": "Compose"
},
"Convert_txt_into_array": {
"inputs": "#split(body('Get_blob_content_(V2)'),'\r\n')",
"runAfter": {
"FindingString": [
"Succeeded"
]
},
"type": "Compose"
},
"FindingString": {
"inputs": {
"variables": [
{
"name": "FindingString",
"type": "string",
"value": "age-34"
}
]
},
"runAfter": {
"Get_blob_content_(V2)": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Get_blob_content_(V2)": {
"inputs": {
"host": {
"connection": {
"name": "#parameters('$connections')['azureblob_1']['connectionId']"
}
},
"method": "get",
"path": "/v2/datasets/#{encodeURIComponent(encodeURIComponent('AccountNameFromSettings'))}/files/#{encodeURIComponent(encodeURIComponent('JTJmY29udGFpbmVyJTJmc2FtcGxlVGV4dEZpbGUudHh0'))}/content",
"queries": {
"inferContentType": true
}
},
"metadata": {
"JTJmY29udGFpbmVyJTJmc2FtcGxlVGV4dEZpbGUudHh0": "/container/sampleTextFile.txt"
},
"runAfter": {},
"type": "ApiConnection"
},
"Index": {
"inputs": {
"variables": [
{
"name": "Index",
"type": "integer",
"value": 0
}
]
},
"runAfter": {
"Convert_txt_into_array": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Status": {
"inputs": {
"variables": [
{
"name": "Status",
"type": "boolean",
"value": false
}
]
},
"runAfter": {
"Index": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Until": {
"actions": {
"Condition": {
"actions": {
"Set_Index": {
"inputs": {
"name": "Index",
"value": "#iterationIndexes('Until')"
},
"runAfter": {
"Set_Status_as_True": [
"Succeeded"
]
},
"type": "SetVariable"
},
"Set_Status_as_True": {
"inputs": {
"name": "Status",
"value": "#true"
},
"runAfter": {},
"type": "SetVariable"
}
},
"else": {
"actions": {
"Set_Status_as_False": {
"inputs": {
"name": "Status",
"value": "#false"
},
"runAfter": {},
"type": "SetVariable"
}
}
},
"expression": {
"and": [
{
"equals": [
"#outputs('Convert_txt_into_array')[variables('Index')]",
"#variables('FindingString')"
]
}
]
},
"runAfter": {},
"type": "If"
},
"Increment_variable": {
"inputs": {
"name": "Index",
"value": 1
},
"runAfter": {
"Condition": [
"Succeeded"
]
},
"type": "IncrementVariable"
}
},
"expression": "#equals(variables('Status'), true)",
"limit": {
"count": 60,
"timeout": "PT1H"
},
"runAfter": {
"Status": [
"Succeeded"
]
},
"type": "Until"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {
"$connections": {
"defaultValue": {},
"type": "Object"
}
},
"triggers": {
"manual": {
"inputs": {
"schema": {}
},
"kind": "Http",
"type": "Request"
}
}
},
"parameters": {
"$connections": {
"value": {
"azureblob_1": {
"connectionId": "/subscriptions/<Your_Subscription_Id>/resourceGroups/<Your_Resource_Group_Name>/providers/Microsoft.Web/connections/azureblob-1",
"connectionName": "azureblob-1",
"id": "/subscriptions/<Your_Subscription_Id>/providers/Microsoft.Web/locations/northcentralus/managedApis/azureblob"
}
}
}
}
}
This solution may not be for you but it's an option.
When you process your CSV data, instead of just adding line by line to the array, you could add an object that contains the index of each row (starting from 0). This is an example of what I mean ...
CSV File
This is a test 1
This is a test 2
This is a test 3
This is a test 4
Reference Array Variable (with objects)
[
{
"Index": 0,
"Text": "This is a test 1"
},
{
"Index": 1,
"Text": "This is a test 2"
},
{
"Index": 2,
"Text": "This is a test 3"
},
{
"Index": 3,
"Text": "This is a test 4"
}
]
You can then filter that array using the Filter array data operation like so ...
Left Side Expression = item()?['Text']
Right Side Expression = string(3) (I'm searching for a string of 3 but because it's a number, I need to treat it slightly differently, it's unlikely you'll have this problem)
That filter produces this result ...
... from which you can get the index of the first found item ...
This is the expression ...
if(greater(length(body('Filter_array')), 0), first(body('Filter_array'))['Index'], -1)
... and there you go ...
This is the JSON definition if you're interested.
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Filter_array": {
"inputs": {
"from": "#variables('Reference Array')",
"where": "#contains(item()?['Text'], string(3))"
},
"runAfter": {
"Initialize_Reference_Array": [
"Succeeded"
]
},
"type": "Query"
},
"Initialize_Found_Index": {
"inputs": {
"variables": [
{
"name": "Found Index",
"type": "integer",
"value": "#if(greater(length(body('Filter_array')), 0), first(body('Filter_array'))['Index'], -1)"
}
]
},
"runAfter": {
"Filter_array": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Initialize_Reference_Array": {
"inputs": {
"variables": [
{
"name": "Reference Array",
"type": "array",
"value": [
{
"Index": 0,
"Text": "This is a test 1"
},
{
"Index": 1,
"Text": "This is a test 2"
},
{
"Index": 2,
"Text": "This is a test 3"
},
{
"Index": 3,
"Text": "This is a test 4"
}
]
}
]
},
"runAfter": {},
"type": "InitializeVariable"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {},
"triggers": {
"Recurrence": {
"evaluatedRecurrence": {
"frequency": "Month",
"interval": 3
},
"recurrence": {
"frequency": "Month",
"interval": 3
},
"type": "Recurrence"
}
}
},
"parameters": {}
}
I have parsed a JSON string in Logic Apps using the parse json connector. How do I put the output from that step into an xml file?
One suggestion I've seen is to use "when a http request is received", but this is a trigger and I need an action.
On user voice there is a request for a parse xml function
here
. I need a workaround.
Another problem I'm having is that parse json is returning an object, but I think I need an array.
This is the schema in my parse json connector. After parse json I'm trying to initialise a variable. It's not accepting a type of string.
<code>
{
"properties": {
"PR_ADD1": {
"type": "string"
},
"PR_ADD2": {
"type": "string"
},
"PR_ADD3": {
"type": "string"
},
"RLS_GROUP": {
"type": "string"
}
},
"title": "The Root Schema",
"type": "object"
}
</code>
How do I initialize the first variable as string with the output from my
previous parse json step? In [this example]
(https://learn.microsoft.com/en-us/azure/logic-apps/logic-apps-perform-
data-operations#parse-json-action) there is only one record. My parse
json step has lots of records.
Here is some sample JSON
<code>
{
"properties": {
"PR_ADD1": {
"type": "string"
},
"PR_ADD2": {
"type": "string"
},
"PR_ADD3": {
"type": "string"
},
"PR_ZONEC": {
"type": "string"
},
"RLS_GROUP": {
"type": "string"
}
},
"title": "The Root Schema",
"type": "object"
}
</code>
Here is my Logic APP
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Compose_2": {
"inputs": "#length(variables('IntermediateArray'))",
"runAfter": {
"Scope": [
"Succeeded"
],
"Set_variable": [
"Succeeded",
"Skipped"
]
},
"type": "compose"
},
"Compose_From_HTTP2": {
"inputs": "#body('HTTP_2')",
"runAfter": {
"HTTP_2": [
"Succeeded"
]
},
"type": "compose"
},
"HTTP_2": {
"inputs": {
"body": {
"FORMAT": "payload",
"FROM": 0,
"GRIDID": "PROP",
"GRIDVIEW": "1",
"HITS": 100,
"ORDERBY": "PR_DATESOLD",
"PROFILE": [
{
"PR_NAME": "G*",
"PR_USER1": "GENERATED"
}
],
"sessionID": "#body('Parse_JSON3')['sessionID']"
},
"headers": {
"Accept": "text/json",
"Content-Type": "text/json"
},
"method": "POST",
"uri": "#variables('uri_DefGrid')"
},
"runAfter": {
"Parse_JSON3": [
"Succeeded"
]
},
"type": "Http"
},
"HTTP_Logout": {
"inputs": {
"body": {
"method": "logout",
"sessionID": "#body('Parse_JSON3')['sessionID']"
},
"headers": {
"Accept": "text/json",
"Content-Type": "text/json"
},
"method": "POST",
"uri": "#variables('uri_logout')"
},
"runAfter": {
"Initialize_uri_logout": [
"Succeeded"
]
},
"type": "Http"
},
"Initialize_Header": {
"inputs": {
"variables": [
{
"name": "Header",
"type": "string",
"value": "{\"Accept\":\"text/json\",\"Content-Type\":\"text/json\"}"
}
]
},
"runAfter": {
"Initialize_body_login": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Initialize_body_login": {
"inputs": {
"variables": [
{
"name": "body_login",
"type": "string",
"value": "json(#{triggerBody()})"
}
]
},
"runAfter": {},
"type": "InitializeVariable"
},
"Initialize_intermediateArray": {
"inputs": {
"variables": [
{
"name": "intermediateArray",
"type": "array"
}
]
},
"runAfter": {
"Compose_From_HTTP2": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Initialize_sharepointLibraryPath": {
"inputs": {
"variables": [
{
"name": "sharepointLibraryPath",
"type": "string",
"value": "https://qqqonline.sharepoint.com/teams-and-projects/dev/hhh"
}
]
},
"runAfter": {
"Compose_2": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Initialize_uri_DefGrid": {
"inputs": {
"variables": [
{
"name": "uri_DefGrid",
"type": "string",
"value": "https://mh-uat.ttt-app.uk:443/qqq_uat/wrd/run/pppMHAPI.GRIDGET"
}
]
},
"runAfter": {
"Initialize_uri_login": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Initialize_uri_login": {
"inputs": {
"variables": [
{
"name": "uri_login",
"type": "string",
"value": "https://mh-uat.ttt-app.uk:443/qqq_uat/wrd/run/pppJSONSERVICE.LOGIN"
}
]
},
"runAfter": {
"Initialize_Header": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Initialize_uri_logout": {
"inputs": {
"variables": [
{
"name": "uri_logout",
"type": "string",
"value": "https://mh-uat.ttt-app.uk:443/qqq_uat/wrd/run/pppJSONSERVICE.LOGOUT"
}
]
},
"runAfter": {
"Initialize_sharepointLibraryPath": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Initialize_variable": {
"inputs": {
"variables": [
{
"name": "initializeArray",
"type": "array",
"value": "#outputs('Compose_From_HTTP2')"
}
]
},
"runAfter": {
"Initialize_intermediateArray": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Parse_JSON3": {
"inputs": {
"content": "#triggerBody()",
"schema": {
"properties": {
"RLS_WHERE": {
"$id": "#/properties/RLS_WHERE",
"type": "string"
},
"contact": {
"type": "string"
},
"error": {
"type": "string"
},
"errorId": {
"type": "string"
},
"fullName": {
"type": "string"
},
"labellanguage": {
"type": "string"
},
"language": {
"type": "string"
},
"message": {
"type": "string"
},
"params": {
"properties": {
"WOPARTSOPT": {
"type": "string"
}
},
"required": [
"WOPARTSOPT"
],
"title": "The Params Schema",
"type": "object"
},
"role": {
"type": "string"
},
"sessionID": {
"type": "string"
},
"success": {
"type": "string"
},
"userEmail": {
"$id": "#/properties/userEmail",
"type": "string"
}
},
"required": [
"success",
"message",
"sessionID",
"language",
"labellanguage",
"error",
"errorId",
"fullName",
"role",
"contact",
"RLS_WHERE",
"userEmail",
"params"
],
"title": "The Root Schema",
"type": "object"
}
},
"runAfter": {
"Initialize_uri_DefGrid": [
"Succeeded"
]
},
"type": "ParseJson"
},
"Scope": {
"actions": {
"Scope_2": {
"actions": {
"Compose": {
"inputs": "#array(outputs('Compose_From_HTTP2'))",
"runAfter": {},
"type": "compose"
},
"Set_variable_2": {
"inputs": {
"name": "intermediateArray",
"value": "#outputs('Compose')"
},
"runAfter": {
"Compose": [
"Succeeded"
]
},
"type": "SetVariable"
}
},
"runAfter": {},
"type": "Scope"
}
},
"runAfter": {
"Initialize_variable": [
"Failed"
]
},
"type": "Scope"
},
"Set_variable": {
"inputs": {
"name": "intermediateArray",
"value": "#outputs('Compose_From_HTTP2')"
},
"runAfter": {
"Initialize_variable": [
"Succeeded"
]
},
"type": "SetVariable"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {},
"triggers": {
"HTTP": {
"inputs": {
"body": {
"method": "login",
"password": "qqq_API",
"username": "qqq_API"
},
"headers": {
"Accept": "text/json",
"Content-Type": "text/json"
},
"method": "POST",
"uri": "https://mh-uat.ttt-app.uk:443/qqq_uat/wrd/run/pppJSONSERVICE.LOGIN"
},
"recurrence": {
"frequency": "Minute",
"interval": 4
},
"type": "Http"
}
}
},
"parameters": {}
}
The parse json screenshot showed the top of the schema. Here is the bottom.
"RLS_GROUP": {
"type": "string"
}
},
"title": "The Root Schema",
"type": "object"
}
When I generate the schema from sample output in parse json I get error messages like this. I think that when integer fields have not value they are coming back with two double quotes to denote empty rather than null. Also, I think the schema is basing itself on the first record which could have data. Subsequent records may not. Conversely the first record may not have data for a particular field, but subsequent records will have data for that field.
"message": "Invalid type. Expected Integer but got String.",
"lineNumber": 0,
"linePosition": 0,
"path": "Payload[1].PR_RENT",
"value": "",
"schemaId": "#/properties/Payload/items/properties/PR_RENT",
"errorType": "type",
"childErrors": []
},
{
"message": "Invalid type. Expected String but got Integer.",
"lineNumber": 0,
"linePosition": 0,
"path": "Payload[3].PR_ID",
"value": 1363,
"schemaId": "#/properties/Payload/items/properties/PR_ID",
"errorType": "type",
"childErrors": []
},
{
"message": "Invalid type. Expected String but got Integer.",
"lineNumber": 0,
"linePosition": 0,
"path": "Payload[3].PR_USER8",
"value": 0,
"schemaId": "#/properties/Payload/items/properties/PR_USER8",
"errorType": "type",
"childErrors": []
}
1. For your first question, we can use xml() method in logic app to do the convert. As I don't know your json data(you mentioned it is a json string in your question), so I assuming that your data is like the data below:
[
{
"name": "Mike",
"city": "ABC"
},
{
"name": "Tom",
"city": "DEF"
}
]
Then we can convert it by following the steps in the screenshot below:
The expression in the screenshot is:
xml(json(concat('{"root":{"person":', variables('test'), '}}')))
After that, we can get the xml data at last:
<root><person><name>Mike</name><city>ABC</city></person><person><name>Tom</name><city>DEF</city></person></root>
2. For your second question about return object or array, it depends on the data you input to the "Parse JSON" action.
If you input the data which is array shown as the screenshot below
We will get a array return from the "Parse JSON" action
If you input the data which is object shown as the screenshot below
We will get an object return from the "Parse JSON" action
Hope it would be helpful to your problems~
Update:
According to your comments, you want to choose some of the fields from the "Parse JSON" and then convert it to xml. I post an example below for your reference:
I assume that your data is like this:
{
"PR_ADD1": "aaa",
"PR_ADD2": "bbb",
"PR_ADD3": "ccc",
"PR_ZONEC": "ddd",
"RLS_GROUP": "eee"
}
And in after parse json, I assume you don't want the field "PR_ZONEC" and keep other four fields, and convert them to xml. So please refer to my logic app:
I do the "Parse JSON" action.
Then, use "Compose" action, and in "Compose" action I remove the field "PR_ZONEC", keep the other four fields.
At last, convert it to xml.
The expression is
xml(json(concat('{"root":', string(outputs('Compose')), '}')))
After these steps, I got the result I want.
The whole of the xml is
<root>
<PR_ADD1>aaa</PR_ADD1>
<PR_ADD2>bbb</PR_ADD2>
<PR_ADD3>ccc</PR_ADD3>
<RLS_GROUP>eee</RLS_GROUP>
</root>