2014-01-17 7 views
2

У меня есть следующие XMLPopulate класса из XML с помощью Linq

<?xml version="1.0" encoding="utf-8"?> 
<Applications xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
<Blocks> 
    <Block Name="block1"> 
     <Attributes> 
      <Tag>Attribute1</Tag> 
      <Layer>layer1</Layer> 
     </Attributes> 
     <Attributes> 
      <Tag>Attribute2</Tag> 
      <Layer>layer2</Layer> 
     </Attributes> 
    </Block> 
    <Block Name="block2"> 
     <Attributes> 
      <Tag>Attribute1</Tag> 
      <Layer>layer0</Layer> 
     </Attributes> 
    </Block> 
</Blocks> 
</Applications> 

Я хотел бы использовать Linq заявление, чтобы охватить все детали и заполнить список со следующим классом. т.е. Список

public class Block 
{  
public string Tag { get; set; } 
    public string Layer { get; set; } 
} 

Я пытался ...

List<Block> data = 
(from a in xdoc.Root.Elements("Blocks") 
where (string)a.Attribute("Name") == "block1" 
select new Block 
{ 
    Tag = (string)a.Element("Tag"), 
    Layer = (string)a.Element("Layer") 
}).ToList(); 

Вы можете увидеть, где я собираюсь неправильно, мало знакомы с LINQ.

+1

попробовать 'xdoc.Root.Elements ("блоки") элементы ("блок")' –

+2

Вы получаете исключение? Это, похоже, не является корректным XML. '' не закрывается, вложенные элементы представляют собой смешанный регистр '' vs ''. Можете ли вы его проверить и исправить? –

+0

Извиняется, я изменил оригинал xml, чтобы опубликовать вопрос ... следовательно, ошибка – user1641194

ответ

3

Try:

LAMBDA Синтаксис:

xdoc.Root.Elements("Blocks").Elements("Block") 
    .Where(w => (string)w.Attribute("Name") == "block1") 
    .Elements("Attributes") 
    .Select(s => new Block 
    { 
     Tag = (string)s.Element("Tag"), 
     Layer = (string)s.Element("Layer") 
    }); 

Если вы хотите использовать синтаксис запроса:

from a in (from b in xdoc.Root.Elements("Blocks").Elements("Block") 
     where (string)b.Attribute("Name") == "block1" 
     select b).Elements("Attributes") 
     select new Block 
     { 
      Tag = (string)a.Element("Tag"), 
      Layer = (string)a.Element("Layer") 
     }; 
+0

Удивительно, спасибо всем за вашу помощь - Кажется, что нужно хорошо работать – user1641194

1

Вы почти у цели.

Fix ваше заявление LINQ немного:

List<Block> data = (from a in (from b in xdoc.Root.Elements("Blocks").Elements("Block") 
           where b.Attribute("Name").Value.Equals("block1") 
           select b).Elements("Attributes") 
        select new Block() 
        { 
         Tag = a.Element("Attributes").Element("Tag").Value, 
         Layer = a.Element("Attributes").Element("Layer").Value 
        }).ToList(); 

сделать Кроме того, что ваш XML является действительным, так как вы смешиваете случаев. Кроме того, согласно @ Grant-Winney, ваш тег приложения все еще открыт в вашем примере.

+0

Запрос по-прежнему не возвращает никаких результатов? – user1641194

+0

Если вы используете пространства имен в своем xml, вам может потребоваться добавить их в запросы с помощью объекта 'XNamespace'. См. Http://stackoverflow.com/questions/2340411/use-linq-to-xml-with-xml-namespaces – JNYRanger

+0

Хорошо, запрос работает, но он возвращает только одно значение атрибута, но block1 имеет 2 атрибута – user1641194

0

Это должно выполнить эту работу.

 var blocks = xdoc.Descendants("Attributes").Select(x => new Block 
      { 
       Tag = x.Descendants("Tag").Single().Value, 
       Layer = x.Descendants("Layer").Single().Value 
      }).ToList(); 
+0

Lambdas обычно сложны для новых пользователей linq, поскольку большинство людей уже знакомы с SQL-подобными запросами. Хотя это будет работать в этом случае, это не очень прощает в зависимости от XML. – JNYRanger

2

Согласно вашему XML-документа, я предлагаю вы меняете свой класс как это:

public class Block 
{  
    public string Name { get; set; } 
    public List<BlockAttribute> Attributes { get; set; } 
} 
public class BlockAttribute 
{ 
    public string Tag { get; set; } 
    public string Layer { get; set; } 
} 

Затем используйте этот код:.

var blocks = (from b in xdoc.Descendants("Block") 
       select new Block { 
          Name = (string)b.Attribute("Name"), 
          Attributes = (from a in b.Elements("Attributes") 
              select new BlockAttribute { 
                Tag = (string)a.Element("Tag"), 
                Layer = (string)a.Element("Layer") 
                }).ToList() 
            }).ToList(); 
Смежные вопросы