I have below XML in SQL Server and wants to iterate over it in order to generate a structured message.
<aggregate type="ApplicationForm">
<entity type="Form" root="true" id="d799728b-7973-4046-b60f-cb25d4ee385c">
<attribute name="creationDate" multivalue="false">2017-01-16</attribute>
<attribute name="product" multivalue="false">Abc</attribute>
<relation name="r_PersonMain" multivalue="false">4808f654-f480-412c-8dc5-d29c6c811602</relation>
<relation name="r_PersonPayer" multivalue="false">a8e9eaf2-56a5-4f88-955b-19eb98f6e882</relation>
</entity>
<entity type="Payment" root="true" id="e197bf66-1e35-42a9-bdc0-0674e3a0f765">
<attribute name="totalAnnualPremium" multivalue="false">328415.81</attribute>
<relation name="r_PaymentMethodRecurring" multivalue="false">b8b3c652-b886-44aa-a75b-b2d3ecd6c064</relation>
<relation name="r_PaymentMethodFirst" multivalue="false">f3d91f99-ff6a-4888-a663-24e42ecc7342</relation>
<attribute name="term" multivalue="false">01</attribute>
</entity>
<entity type="Person" root="false" id="4808f654-f480-412c-8dc5-d29c6c811602">
<relation name="r_AddressWork" multivalue="false">cae83657-47c2-49bd-a588-7685271c4766</relation>
<attribute name="idNumber" multivalue="false">1112223334447</attribute>
<relation name="r_SelectionItem" multivalue="true">...</relation>
<relation name="r_Health" multivalue="false">07d08bd6-ec73-4710-9de4-23435cd2b088</relation>
<relation name="r_AddressCurrent" multivalue="false">56d17bda-e332-497e-8e22-e7b7f09f996d</relation>
<attribute name="lastName" multivalue="false"> 1</attribute>
<attribute name="jobDescription1" multivalue="false"/>
<relation name="r_Behavior" multivalue="false">2db2c23a-37dd-4857-87b4-005aa87b2c2d</relation>
<attribute name="email" multivalue="false"></attribute>
<relation name="r_AddressRegistered" multivalue="false">ce79a468-fb26-4996-91a8-82954d960855</relation>
<attribute name="telephoneExtention1" multivalue="false"/>
<relation name="r_Occupation1" multivalue="false">b7b69acc-2945-4f64-8ffd-4537849280f5</relation>
</entity>
</aggregate>
The top element contains long list of entity
tags. Each of it contains two elements, attribute
& relation
. The attribute
contains direct values while the relation
contains reference to another entity
tag which in turn contains either attribute
or relation
.
In order to pick out entity
Form (1st tag), it requires to iterate on it and all of its references until all referenced entities
are retrieved.
I can retrieve first entity and its relations (reference entities) and then I access its 2nd level referenced entity and then i again check inside of it if there is another "relation" tag then I have to access it as well.
Problem is, this approach is not dynamic and can not automatically retrieve all referenced items.
Q:- How I can dynamically access all referenced entities and its attributes until there is no referenced entity anymore.
Q:- I also want to give assign tag my custom names based on each attribute or entity "name" tag. for example, creationDate, product.
Here is my query.
DECLARE @xml xml
SET @xml =(Select CAST( CAST([AAHAD].[dbo].[aq_aggregate].data AS NVARCHAR(MAX)) AS XML )
FROM [AAHAD].[dbo].[aq_aggregate]
WHERE [AAHAD].[dbo].[aq_aggregate].[aggregateId] = 2
FOR XML RAW, TYPE)
SELECT @xml.query('
let $xml := (/row/aggregate)
let $form := (/row/aggregate/entity[@type="Form"])
return
<Form>
<attributes>
{
for $form_attrs in ($form/attribute)
return <attribute><name>{ data($form_attrs/@name) } </name><value>{ data($form_attrs) }</value></attribute>
}
</attributes>
<relations>
{
for $form_rel in ($form/relation)
let $form_rel_id := data($form_rel)
let $relation :=($xml/entity[@id=$form_rel_id])
return
<relation>
<attributes>
{
for $innerRel_attrs in ($relation/attribute)
return <attribute><name>{ data($innerRel_attrs/@name) } </name><value>{ data($innerRel_attrs) }</value></attribute>
}
</attributes>
<relations>
{
for $innerRel_rel in ($relation/relation)
let $inner_Rel_id := data($innerRel_rel)
let $inner_Relation :=($xml/entity[@id=$inner_Rel_id])
return
<relation>
<attributes>
{
for $inner2Rel_attrs in ($inner_Relation/attribute)
return <attribute><name>{ data($inner2Rel_attrs/@name) } </name><value>{ data($inner2Rel_attrs) }</value></attribute>
}
</attributes>
<relations>
{
for $inner2Rel_rel in ($inner_Relation/relation)
return <relation>{ ($inner2Rel_rel) }</relation>
}
</relations>
</relation>
}
</relations>
</relation>
}
</relations>
</Form>
')