LINQ to XML select subquery attributes into a string list



I'm having some troubles trying to get the needed results from a query and a sub-query list from an XML document.


I have the following XML document (cut down version)





<ObjectSet ExportMode="Special" Version="1.5.0.2307" Note="TypesFirst">
<MetaInformation>
<ExportMode Value="Special" />
<RuntimeVersion Value="1.5.0.2307" />
<SourceVersion Value="1.5.0.2307" />
<ServerFullPath Value="/WW_C27" />
</MetaInformation>
<ExportedObjects>
<OI NAME="Source Notifications" TYPE="system.base.Folder">
<OI NAME="Joe Blow" TYPE="notification.EmailNotification">
<PI Name="EmailAddress" Value="joeblow@myemail.com" />
<PI Name="EmailSubject" Value="TEST ALARM" />
<PI Name="NotificationText" Value="Alarm text: @(AlarmText) Triggered: @(TimeStamp)" />
<PI Name="Status" Value="1" />
<OI NAME="Filter" TYPE="event.filter.Filter" declared="1" hidden="1">
<OI NAME="AlarmState" TYPE="event.filter.expression.Enum" declared="1"></OI>
<OI NAME="Source" TYPE="event.filter.expression.Text" flags="aggregated">
<PI Name="Column" Value="Source" />
<PI Name="DisplayName" Value="Source" />
<OI NAME="Value1" TYPE="event.filter.expression.TextValue" flags="aggregated">
<PI Name="Value" Value="LG Gas Panel Exhaust Fan" />
</OI>
<OI NAME="Value3" TYPE="event.filter.expression.TextValue" flags="aggregated">
<PI Name="Value" Value="LG Dewer Alm" />
</OI>
</OI>
</OI>
</OI>
<OI NAME="John Smith" TYPE="notification.EmailNotification">
<PI Name="EmailAddress" Value="johnsmith@myemail.com" />
<PI Name="EmailSubject" Value="Work ALARM" />
<PI Name="NotificationText" Value="Alarm text: @(AlarmText) Triggered: @(TimeStamp)" />
<PI Name="Status" Value="1" />
<OI NAME="Filter" TYPE="event.filter.Filter" declared="1" hidden="1">
<OI NAME="AlarmState" TYPE="event.filter.expression.Enum" declared="1">
<PI Name="Column" Value="AlarmState" />
<PI Name="DisplayName" Value="Alarm state" />
<PI Name="EnumType" Value="alarm.pt.AlarmState" />
<OI NAME="1" TYPE="event.filter.expression.EnumValue" flags="aggregated">
<PI Name="Value" Value="1" />
</OI>
<OI NAME="0" TYPE="event.filter.expression.EnumValue" flags="aggregated" /></OI>
<OI NAME="Source" TYPE="event.filter.expression.Text" flags="aggregated">
<PI Name="Column" Value="Source" />
<PI Name="DisplayName" Value="Source" />
<OI NAME="Value1" TYPE="event.filter.expression.TextValue" flags="aggregated">
<PI Name="Value" Value="Rm 7 FrzAlm" />
</OI>
<OI NAME="Value2" TYPE="event.filter.expression.TextValue" flags="aggregated">
<PI Name="Value" Value="Dewer Alm" />
</OI>
</OI>
</OI>
</OI>
</OI>
</ExportedObjects>
</ObjectSet>



In summary, I need to extract from the above XML document the following details:



  • Person Name

  • Person Email Address

  • Email Subject


All of the above details I'm able to extract and display on my datagrid.


However, for every user there are a number of alarm messages that I need to display in the datagrid, as child rows underneath the datagrid's given user. I'm not able to do so at the moment. What is the best way to achieve the required outcome?


From the above XML document, the following is a typical element, that I need to extract as a child list under each user:





<PI Name="Value" Value="Dewer Alm" />


See below my C# code.



List<EmailNotificationClass> NotificationList =
(
from n in XDocument.Load(str_XMLFilePath).Root.Descendants("ExportedObjects").Descendants("OI").Descendants("OI")
where (string)n.Attribute("TYPE") == "notification.EmailNotification"

let attrib_NAME = n.Attribute("NAME")

let attrib_EMAIL = n.XPathSelectElement("./PI[@Name='EmailAddress']").Attribute("Value")
let attrib_SUBJECT = n.XPathSelectElement("./PI[@Name='EmailSubject']").Attribute("Value")
let attrib_NotificationText = n.XPathSelectElement("./PI[@Name='NotificationText']").Attribute("Value")
let attrib_Status = n.XPathSelectElement("./PI[@Name='Status']").Attribute("Value")

let attrib_SourceList = n.XPathSelectElement("//OI/OI[@NAME='Source']/OI/PI[@Name='Value']")



select new EmailNotificationClass
{
EN_NotificationName = attrib_NAME.Value,
EN_EmailAddress = attrib_EMAIL.Value,
EN_EmailSubject = attrib_SUBJECT.Value,
EN_NotificationText = attrib_NotificationText.Value,
EN_Status = attrib_Status.Value,

EN_SourceList = attrib_SourceList.Value //Need to turn this result into a child list
}
).ToList();

//Set DataGrid source
DG_Notifications.ItemsSource = NotificationList;

}
else
{
MessageBox.Show("Please load XML file from the import tab first");
}
}


Any help will be much appreciated.


Cheers


Alain


No comments:

Post a Comment