2017-01-30 4 views
3

Я довольно новичок на этом веб-сайте, это мой первый вопрос. Я прочитал документацию, но извините заранее, если я заблокирую любой кодекс поведения. Зашел свой вопрос:C# Linq для XML: tag.descendants не позволяет допросить всех потомков

У меня есть XML-файл в потоке. Моя цель - получить атрибут «Имя», «Тип» и ключ или ключи (они были изменены по понятной причине).

<YourKey> 
<Product_Key Name="eMbedded Visual C++ 4.0"> 
<Key ID="5" Type="Static Activation Key" ClaimedDate="">BBBBB-QW36D-DPT6T-BBBB-ZZZZZ</Key> 
</Product_Key> 
<Product_Key Name="Windows 10 Home"> 
<Key ID="1251" Type="Retail" ClaimedDate="1/25/2017">ZZZZZ-6GBG7-ZZZZZ-8JG23-FM47H</Key> 
<Key ID="1251" Type="Retail" ClaimedDate="8/23/2016">FEFEF-FVD7K-EEEEF-BEBEB-VMHX7</Key> 
<Key ID="1251" Type="Retail" ClaimedDate="4/28/2016">EEZZE-GYB6P-ZZZEE-R72PQ-EEEEZ</Key> 
</Product_Key> 
</YourKey> 

Я создал класс для хранения данных

public class MsProduct 
    { 
     public string Name { get; set; } 
     public string Type { get; set; } 
     public List<string> key { get; set; } 
    } 

И я создал список MsProduct добавить каждые элементы из var list (см после) к моему объекту.

Я создал запрос Linq, он компилируется без Key = (List<string>)keys, но я получаю только значение Name, Type пусто (у меня есть проверка, нет ли данных (т.е. == null), заменить его на "").

Когда я добавляю Key = (List<string>)keys, система выдает «Исключение System.InvalidCastException».

вот мой запрос:

var productName = XDocument.Load(fileXml); 
var list = from product in productName.Descendants("YourKey") 
        let name = product.Attribute("Name") 
        let type = product.Attribute("Type") 
        let keys = product.Elements("Key") 
        select new MsProduct 
        { 
         Name = (string)name, 
         Type = (string)type, 
         Key = (List<string>)keys 
        }; 

Кто-нибудь есть идеи, как запросить мой файл, чтобы заселить свой класс?

Заранее благодарен!

+1

Тип - атрибут Ключа, а не продукта. Прокомментируйте эту строку и проверьте. Еще одна вещь: ваш XML недействителен. – A3006

+0

Благодарим за быстрый ответ. XML поставляется непосредственно из Microsoft, это экспорт моего субстрата MSDN. Я не создал код;). На ключ ответил ответ, чуть ниже, теперь мне интересно, как получить «тип». –

ответ

2

Ваши ключи не являются строками, а XElements, вы не можете наложить его на string. В зависимости от того, что вы хотите получить, вы можете сделать:

Key = (List<string>)keys.Select(x=>x.Value).ToList() 

или

Key = (List<string>)keys.Select(x=>x.ToString()).ToList() 

Но вы не получите ничего на вашем XML, потому что вы запрашиваете не продукты, но YourKey «S, чтобы получить продукты изменить первую строку на:

var list = from product in productName.Descendants("Product_Key") 

Если вы хотите получить тип, вы должны учитывать, что у вас есть более чем один тип про продукт. Либо вы запрашиваете типы в список, как ключи, или вы уверены, что все они одинаковы, так что вы можете взять только первый:

var list = from product in productName.Descendants("Product_Key") 
      let name = product.Attribute("Name")    
      let keys = product.Elements("Key") 
      select new MsProduct 
      { 
       Name = (string)name, 
       Type = keys.First().Attribute("Type").Value, 
       Key = (List<string>)keys.Select(x=>x.Value).ToList() 
      }; 
+0

Благодарим за быстрый ответ. Это решило проблему, с которой я столкнулся со списком ключей, но мой 'тип' все еще пуст. Я меняю его на: let type = productName.Descendants (« Key »). Атрибуты (« Тип ») Тип = (строка) type.Select (х => x.Value) .ToString(), Но теперь, значение 'type' является " Тип \t" System.Linq.Enumerable + WhereSelectEnumerableIterator'2 [System.Xml. Linq.XAttribute, System.String] "\t string " –

+0

Что вы хотите видеть как тип? Например, «Статический ключ активации»? –

+0

Да, у меня есть статический ключ активации, розничная или MultipleActivation в файле, и мне нужна эта информация для моего программного обеспечения. –

2

Вам не нужны эти let заявления. Вам нужно получить значения из ваших ключей.

var list = from product in productName.Descendants("Product_Key") 
       where product.Attribute("Name").Value == "YourKey" 
      // let name = product.Attribute("Name") 
      // let type = product.Attribute("Type") 
      // let keys = product.Elements("Key") 
       select new MsProduct 
       { 
        Name = (string)product.Attribute("Name"), 
        Type = product.Elements("Type").First().Attribute("Type").Value, 
        Key = product.Elements("Key").Select(e=>e.Value).ToList() 
       }; 

Но Elements("Type").First(), конечно, сомнительное определение.
Нет такой вещи, как Тип продуктаKey. Он может иметь много типов.

+0

Он действительно решает проблему для моей проблемы типа. Большое спасибо!!!! Вы не возражаете, я спрашиваю, почему это сомнительное определение? –

+0

Поскольку XML явно позволяет использовать разные типы для одного Product_Key. Поэтому, говоря «Тип», вы получаете неправильные последствия. –