LINQ to XML - Elements() работает, но элементы (XName) не работают

Ниже приведен мой xml:

<?xml version="1.0" encoding="utf-8"?>
<Report xmlns:rd="http://schemas.microsoft.com/SQLServer/reporting/reportdesigner" xmlns="http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition">
    <Body>
        <ReportItems>
            <Textbox Name="txtCurrentDate">
                <CanGrow>true</CanGrow>
                <KeepTogether>true</KeepTogether>
                <Paragraphs>
                    <Paragraph>
                        <TextRuns>
                            <TextRun>
                                <Value>=Today()</Value>
                                <Style>
                                    <FontWeight>Medium</FontWeight>
                                    <Format>d</Format>
                                </Style>
                            </TextRun>
                        </TextRuns>
                        <Style>
                            <TextAlign>Left</TextAlign>
                        </Style>
                    </Paragraph>
                </Paragraphs>
                <Left>0.36958in</Left>
                <Height>0.22917in</Height>
                <Width>1in</Width>
                <Style>
                    <Border>
                        <Style>None</Style>
                    </Border>
                    <PaddingLeft>2pt</PaddingLeft>
                    <PaddingRight>2pt</PaddingRight>
                    <PaddingTop>2pt</PaddingTop>
                    <PaddingBottom>2pt</PaddingBottom>
                </Style>
            </Textbox>
            <Textbox Name="txtName">
                <CanGrow>true</CanGrow>
                <KeepTogether>true</KeepTogether>
                <Paragraphs>
                    <Paragraph>
                        <TextRuns>
                            <TextRun>
                                <Value>Mark Wilkinson</Value>
                                <Style />
                            </TextRun>
                        </TextRuns>
                        <Style />
                    </Paragraph>
                </Paragraphs>
                <Top>0.22917in</Top>
                <Left>0.36958in</Left>
                <Height>0.20833in</Height>
                <Width>3.22917in</Width>
                <ZIndex>1</ZIndex>
                <Style>
                    <Border>
                        <Style>None</Style>
                    </Border>
                    <PaddingLeft>2pt</PaddingLeft>
                    <PaddingRight>2pt</PaddingRight>
                    <PaddingTop>2pt</PaddingTop>
                    <PaddingBottom>2pt</PaddingBottom>
                </Style>
            </Textbox>
        </ReportItems>
        <Height>6.01667in</Height>
        <Style />
    </Body>
    <Width>7.92333in</Width>   
</Report>

Я хочу получить все имена и значения Текстовое поле. Это то, что я пробовал, и он не работает:

XDocument data = XDocument.Load("..\\..\\testxml.rdl");

            var elements = from c in data.Elements("ReportItems")
                           select c;
            foreach (var element in elements)
            {                
                Console.WriteLine("Element : " + element.Attribute("Name").Value);

            }
            Console.ReadKey();

но когда я изменяю запрос на что-то вроде этого

var elements = from c in data.Elements().Elements().ElementAt(0).Elements().ElementAt(0).Elements()
                           select c;

он работает.

Любая помощь в этом отношении очень ценится.

Изменить: с помощью ответов я смог получить желаемые результаты. Большое вам спасибо:)

XDocument data = XDocument.Load("..\\..\\testxml.rdl");            
            XNamespace ns = data.Root.Name.Namespace;
            var elements = from c in data.Descendants(ns + "Textbox")
                           select c;
            foreach (var element in elements)
            {                
                Console.WriteLine("Element : " + element.Attribute("Name").Value);                
            }
            Console.ReadKey();

ТИА.

Раджа

Ответ 1

Вам нужно учитывать пространство имен:

XNamespace df = data.Root.Name.Namespace;

Затем используйте df + "foo" для выбора элементов с локальным именем foo в пространстве имен, определенных в корневом элементе.

И как уже упоминалось, вы, вероятно, захотите выбрать потомки, а не дочерние элементы:

        var elements = from c in data.Descendants(df + "Textbox")
                       select c;

Ответ 2

В этом случае вы ищете Descendants() not Elements(). Elements() выбирает только непосредственных детей.

Documentation

  • XContainer.Descendants Method (XName) - Возвращает отфильтрованную коллекцию элементов-потомков для этого документа или элемента в порядке документа. В коллекцию включены только элементы, имеющие соответствующее имя XName.
  • XContainer.Elements Method (XName) - возвращает отфильтрованную коллекцию дочерних элементов этого элемента или документа в порядке документа. В коллекцию включены только те элементы, которые имеют соответствующее XName.

Примечание. Исходя из вашего примера кода, использование Descendants() все равно вызовет исключение, потому что не все элементы ReportItems имеют атрибут Name. Вам нужно сделать что-то вроде Console.WriteLine("Element : " + (element.Attributes("Name").Any() ? element.Attribute("Name").Value : "(no name)") );

Ответ 3

 if (openFileDialog1.ShowDialog() == DialogResult.OK)
        {
            filepath = openFileDialog1.FileName;
            try
            {

                XElement xe = XElement.Load(filepath);
              // 

                string sql = "insert OR IGNORE into price_list (name,his_code,specs,unit,spell,price) values(@name,@his_code,@specs,@unit,@spell,@price);";
                int count = 0;
                foreach (XElement el in xe.Descendants("row"))
                {
                    SQLiteParameter[] ps =
                    {
                        new SQLiteParameter("@his_code",el.Element("aka079").Value),
                        new SQLiteParameter("@name",el.Element("aka061").Value),
                        new SQLiteParameter("@specs",el.Element("aka073").Value),
                        new SQLiteParameter("@unit",el.Element("aka067").Value),
                        new SQLiteParameter("@spell",SpellCode.GetSpellCode(el.Element("aka061").Value)),
                        new SQLiteParameter("@price",el.Element("aka071").Value),
                    };

                    if (SqliteHelper.ExecuteNonQuery(sql, ps) > 0)
                    {
                        count++;
                    }

                }

            }
            catch (Exception ex)
            {
                MessageBox.Show("Error: Could not read file from disk. Original error: " + ex.Message);
            }

просто измените XElements() на Descendants(), он будет работать, вероятно,