簡體   English   中英

LINQ to XML將子查詢屬性選擇到字符串列表中

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM