![](/img/trans.png)
[英]LINQ to XML - Trying to select a list of elements by the value of their attributes
[英]LINQ to XML select subquery attributes into a string list
我在嘗試從XML文檔的查詢和子查詢列表中獲取所需的結果時遇到了一些麻煩。
我有以下XML文檔(精簡版)
<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>
總之,我需要從上述XML文檔中提取以下詳細信息:
我能夠提取並顯示在我的數據網格上的所有上述詳細信息。
但是,對於每個用戶,我需要在數據網格中顯示許多警報消息,作為數據網格給定用戶下方的子行。 我目前無法這樣做。 實現所需結果的最佳方法是什么?
從上面的XML文檔中,以下是一個典型元素,我需要將其提取為每個用戶下的子列表:
<PI Name="Value" Value="Dewer Alm" />
請參見下面的C#代碼。
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");
}
}
任何幫助都感激不盡。
干杯
阿蘭
設法自己解決問題。 對於可能會遇到類似問題的任何人,問題在於我定義了保存數據的類的方式,該類隨后將顯示在DataGrid中。
將第一個類中的字符串Sources更改為List后,我便能夠檢索到每個人的警報列表。
public class EmailNotificationClass
{
//EN = EmailNotification OI in the XML document
public string EN_NotificationName { get; set; }
public string EN_EmailAddress { get; set; }
public string EN_EmailSubject { get; set; }
public string EN_NotificationText { get; set; }
public string EN_Status { get; set; }
public string EN_FilterType { get; set; }
public List<EN_F_SourceClass> Sources { get; set; }
}
public class EN_F_SourceClass
{
public string FilterSource { get; set; }
}
然后,我修改了后面的代碼,如下所示
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")
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,
Sources =
(
from source in n.XPathSelectElements("OI/OI[@NAME='Source']/OI/PI[@Name='Value']")
select new EN_F_SourceClass
{
FilterSource = (string)source.Attribute("Value")
}).ToList()
}
).ToList();
//Set DataGrid source
DG_Notifications.ItemsSource = NotificationList;
}
else
{
MessageBox.Show("Please load XML file from the import tab first");
}
xalm部分很簡單。 剛剛添加了RowDeetailsTemplate如下
<DataGrid.RowDetailsTemplate> <DataTemplate> <Grid MaxHeight="100"> <ScrollViewer> <Border BorderThickness="0" Background="#FFB8E8A1" Padding="5"> <DataGrid ItemsSource="{Binding Sources}" IsReadOnly="True" SelectionMode="Single" SelectionUnit="FullRow" AutoGenerateColumns="False"> <DataGrid.Columns> <DataGridTextColumn Width="400" Header="Alarms" Binding="{Binding FilterSource}"></DataGridTextColumn> </DataGrid.Columns> </DataGrid> </Border> </ScrollViewer> </Grid> </DataTemplate> </DataGrid.RowDetailsTemplate>
謝謝閱讀,
阿蘭
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.