EDN Admin
Well-known member
I am unable to figure out how to parse an xml based on the following scenario. I am trying to parse a business rule, which is in xml format. Xml file has a grouping of "AND" and "OR" conditions. I need to maintain the hierachy and basically convert that
whole xml into a biztalk rule . I was able to achieve that by using a simple xml which has only one "AND" condition and create a biztalk rule. But now when i created a nested "AND" and "OR" conditions..i am not sure how to parse the innermost "AND" for
example and maintain the hierachy upwards..below is a sample xml
<?xml version="1.0" encoding="utf-8" ?> <br/>
<rule name="TestRule2" priority="0" active="true <br/>
<if><br/>
<and><br/>
<compare operator="equal <br/>
<lhs><br/>
<function><br/>
<xmldocumentmember xmldocumentref="xml_31" type="string" sideeffects="false <br/>
<fieldalias>AccountID</fieldalias> <br/>
</xmldocumentmember><br/>
</function><br/>
</lhs><br/>
<rhs><br/>
<constant><br/>
<string>1234</string> <br/>
</constant><br/>
</rhs><br/>
</compare><br/>
<compare operator="not equal <br/>
<lhs><br/>
<function><br/>
<xmldocumentmember xmldocumentref="xml_31" type="string" sideeffects="false <br/>
<fieldalias>CompanyID</fieldalias> <br/>
</xmldocumentmember><br/>
</function><br/>
</lhs><br/>
<rhs><br/>
<constant><br/>
<string>1111</string> <br/>
</constant><br/>
</rhs><br/>
</compare><br/>
<and><br/>
<compare operator="equal <br/>
<lhs><br/>
<function><br/>
<br/>
<xmldocumentmember xmldocumentref="xml_32" type="string" sideeffects="false <br/>
<field>@*[local-name()=AccountID and namespace-uri()=]</field><br/>
<fieldalias>@AccountID</fieldalias><br/>
</xmldocumentmember><br/>
</function><br/>
</lhs><br/>
<rhs><br/>
<constant><br/>
<string>1234</string><br/>
</constant><br/>
</rhs><br/>
</compare><br/>
<or><br/>
<compare operator="equal <br/>
<lhs><br/>
<function><br/>
<br/>
<xmldocumentmember xmldocumentref="xml_33" type="string" sideeffects="false <br/>
<field>.</field><br/>
<fieldalias>@AccountStatus</fieldalias><br/>
</xmldocumentmember><br/>
</function><br/>
</lhs><br/>
<rhs><br/>
<constant><br/>
<string>2121</string><br/>
</constant><br/>
</rhs><br/>
</compare><br/>
<compare operator="equal <br/>
<lhs><br/>
<function><br/>
<xmldocumentmember xmldocumentref="xml_34" type="string" sideeffects="false <br/>
<field>.</field><br/>
<fieldalias>@AccomodationCode</fieldalias><br/>
</xmldocumentmember><br/>
</function><br/>
</lhs><br/>
<rhs><br/>
<constant><br/>
<string>11</string><br/>
</constant><br/>
</rhs><br/>
</compare><br/>
</or><br/>
</and><br/>
</and><br/>
</if><br/>
</rule>
below is the code i wrte to get the parsing working if there was only one "AND" in the rule xml above. I am newbie to LINQ. Please suggest if you see any code issues.
<span style="font-size:small var LogicalANDConditions = from items in XDoc.Descendants("and")<br/>
select new<br/>
{
<span style="font-size:small
//LHSFields = items.Descendants("LHS"),<br/>
//RHSFields
= items.Descendants("RHS")
<span style="font-size:small
LogicalExprnXml = items.Descendants("compare")
<span style="font-size:small
<br/>
};
LogicalExpressionCollection LogicalExprnCollection = new LogicalExpressionCollection();<br/>
XMLDocumentFieldBinding LHSFieldBinding = null;<br/>
XMLDocumentFieldBinding RHSFieldBinding = null;<br/>
foreach (var ANDCondition in LogicalANDConditions)<br/>
{
foreach (var LogicalExprnStmt in ANDCondition.LogicalExprnXml)<br/>
{
var predicate = LogicalExprnStmt.FirstAttribute.Value;<br/>
var RHSVocabName = string.Empty;<br/>
var LHSVocabName = string.Empty;<br/>
Constant RHSConstant = null;<br/>
var LHSFieldNode = LogicalExprnStmt.FirstNode.ToString();<br/>
var LHSField = LogicalExprnStmt.Elements("lhs");<br/>
var LHSFieldType = LHSFieldNode.Contains("function");<br/>
if (LHSFieldType == true)<br/>
{<br/>
LHSVocabName = LHSField.Descendants("fieldalias").First().Value;<br/>
LHSFieldBinding = RuleVocabDictionary[LHSVocabName];<br/>
<br/>
}<br/>
var RHSFieldNode = LogicalExprnStmt.LastNode.ToString();<br/>
var RHSField = LogicalExprnStmt.Elements("rhs");<br/>
var RHSFieldType = RHSFieldNode.Contains("function");<br/>
if (RHSFieldType == true)<br/>
{<br/>
RHSVocabName = RHSField.Descendants("fieldalias").First().Value;<br/>
RHSFieldBinding = RuleVocabDictionary[RHSVocabName];<br/>
}<br/>
else<br/>
{<br/>
RHSVocabName = RHSField.Descendants("constant").First().Value;<br/>
RHSConstant = new Constant(RHSVocabName);<br/>
var x = RHSConstant.VocabularyLink;<br/>
}
<br/>
switch (predicate)<br/>
{<br/>
case "equal":<br/>
{<br/>
if (!string.IsNullOrEmpty(RHSConstant.ToString()))<br/>
LogicalExprnCollection.Add(new Equal(new UserFunction(LHSFieldBinding),
RHSConstant));<br/>
else<br/>
LogicalExprnCollection.Add(new Equal(new UserFunction(LHSFieldBinding),
new UserFunction(RHSFieldBinding)));<br/>
break;<br/>
}<br/>
case "not equal":<br/>
{<br/>
if (!string.IsNullOrEmpty(RHSConstant.ToString()))<br/>
LogicalExprnCollection.Add(new Equal(new UserFunction(LHSFieldBinding),
RHSConstant));<br/>
else<br/>
LogicalExprnCollection.Add(new Equal(new UserFunction(LHSFieldBinding),
new UserFunction(RHSFieldBinding)));<br/>
break;
}
}<br/>
}<br/>
}
Please guide me in the right direction to parse the xml and maintain the hierarchy/grouping to create the rule with AND/OR hierarchy in the same order as in the xml.Thank you.
<span style="font-size:small <span style="font-size:small
<a> <a> <hr class="sig Dilip Bandi
View the full article
whole xml into a biztalk rule . I was able to achieve that by using a simple xml which has only one "AND" condition and create a biztalk rule. But now when i created a nested "AND" and "OR" conditions..i am not sure how to parse the innermost "AND" for
example and maintain the hierachy upwards..below is a sample xml
<?xml version="1.0" encoding="utf-8" ?> <br/>
<rule name="TestRule2" priority="0" active="true <br/>
<if><br/>
<and><br/>
<compare operator="equal <br/>
<lhs><br/>
<function><br/>
<xmldocumentmember xmldocumentref="xml_31" type="string" sideeffects="false <br/>
<fieldalias>AccountID</fieldalias> <br/>
</xmldocumentmember><br/>
</function><br/>
</lhs><br/>
<rhs><br/>
<constant><br/>
<string>1234</string> <br/>
</constant><br/>
</rhs><br/>
</compare><br/>
<compare operator="not equal <br/>
<lhs><br/>
<function><br/>
<xmldocumentmember xmldocumentref="xml_31" type="string" sideeffects="false <br/>
<fieldalias>CompanyID</fieldalias> <br/>
</xmldocumentmember><br/>
</function><br/>
</lhs><br/>
<rhs><br/>
<constant><br/>
<string>1111</string> <br/>
</constant><br/>
</rhs><br/>
</compare><br/>
<and><br/>
<compare operator="equal <br/>
<lhs><br/>
<function><br/>
<br/>
<xmldocumentmember xmldocumentref="xml_32" type="string" sideeffects="false <br/>
<field>@*[local-name()=AccountID and namespace-uri()=]</field><br/>
<fieldalias>@AccountID</fieldalias><br/>
</xmldocumentmember><br/>
</function><br/>
</lhs><br/>
<rhs><br/>
<constant><br/>
<string>1234</string><br/>
</constant><br/>
</rhs><br/>
</compare><br/>
<or><br/>
<compare operator="equal <br/>
<lhs><br/>
<function><br/>
<br/>
<xmldocumentmember xmldocumentref="xml_33" type="string" sideeffects="false <br/>
<field>.</field><br/>
<fieldalias>@AccountStatus</fieldalias><br/>
</xmldocumentmember><br/>
</function><br/>
</lhs><br/>
<rhs><br/>
<constant><br/>
<string>2121</string><br/>
</constant><br/>
</rhs><br/>
</compare><br/>
<compare operator="equal <br/>
<lhs><br/>
<function><br/>
<xmldocumentmember xmldocumentref="xml_34" type="string" sideeffects="false <br/>
<field>.</field><br/>
<fieldalias>@AccomodationCode</fieldalias><br/>
</xmldocumentmember><br/>
</function><br/>
</lhs><br/>
<rhs><br/>
<constant><br/>
<string>11</string><br/>
</constant><br/>
</rhs><br/>
</compare><br/>
</or><br/>
</and><br/>
</and><br/>
</if><br/>
</rule>
below is the code i wrte to get the parsing working if there was only one "AND" in the rule xml above. I am newbie to LINQ. Please suggest if you see any code issues.
<span style="font-size:small var LogicalANDConditions = from items in XDoc.Descendants("and")<br/>
select new<br/>
{
<span style="font-size:small
//LHSFields = items.Descendants("LHS"),<br/>
//RHSFields
= items.Descendants("RHS")
<span style="font-size:small
LogicalExprnXml = items.Descendants("compare")
<span style="font-size:small
<br/>
};
LogicalExpressionCollection LogicalExprnCollection = new LogicalExpressionCollection();<br/>
XMLDocumentFieldBinding LHSFieldBinding = null;<br/>
XMLDocumentFieldBinding RHSFieldBinding = null;<br/>
foreach (var ANDCondition in LogicalANDConditions)<br/>
{
foreach (var LogicalExprnStmt in ANDCondition.LogicalExprnXml)<br/>
{
var predicate = LogicalExprnStmt.FirstAttribute.Value;<br/>
var RHSVocabName = string.Empty;<br/>
var LHSVocabName = string.Empty;<br/>
Constant RHSConstant = null;<br/>
var LHSFieldNode = LogicalExprnStmt.FirstNode.ToString();<br/>
var LHSField = LogicalExprnStmt.Elements("lhs");<br/>
var LHSFieldType = LHSFieldNode.Contains("function");<br/>
if (LHSFieldType == true)<br/>
{<br/>
LHSVocabName = LHSField.Descendants("fieldalias").First().Value;<br/>
LHSFieldBinding = RuleVocabDictionary[LHSVocabName];<br/>
<br/>
}<br/>
var RHSFieldNode = LogicalExprnStmt.LastNode.ToString();<br/>
var RHSField = LogicalExprnStmt.Elements("rhs");<br/>
var RHSFieldType = RHSFieldNode.Contains("function");<br/>
if (RHSFieldType == true)<br/>
{<br/>
RHSVocabName = RHSField.Descendants("fieldalias").First().Value;<br/>
RHSFieldBinding = RuleVocabDictionary[RHSVocabName];<br/>
}<br/>
else<br/>
{<br/>
RHSVocabName = RHSField.Descendants("constant").First().Value;<br/>
RHSConstant = new Constant(RHSVocabName);<br/>
var x = RHSConstant.VocabularyLink;<br/>
}
<br/>
switch (predicate)<br/>
{<br/>
case "equal":<br/>
{<br/>
if (!string.IsNullOrEmpty(RHSConstant.ToString()))<br/>
LogicalExprnCollection.Add(new Equal(new UserFunction(LHSFieldBinding),
RHSConstant));<br/>
else<br/>
LogicalExprnCollection.Add(new Equal(new UserFunction(LHSFieldBinding),
new UserFunction(RHSFieldBinding)));<br/>
break;<br/>
}<br/>
case "not equal":<br/>
{<br/>
if (!string.IsNullOrEmpty(RHSConstant.ToString()))<br/>
LogicalExprnCollection.Add(new Equal(new UserFunction(LHSFieldBinding),
RHSConstant));<br/>
else<br/>
LogicalExprnCollection.Add(new Equal(new UserFunction(LHSFieldBinding),
new UserFunction(RHSFieldBinding)));<br/>
break;
}
}<br/>
}<br/>
}
Please guide me in the right direction to parse the xml and maintain the hierarchy/grouping to create the rule with AND/OR hierarchy in the same order as in the xml.Thank you.
<span style="font-size:small <span style="font-size:small
<a> <a> <hr class="sig Dilip Bandi
View the full article