2015-11-28 2 views
-2

У меня есть следующий XML-файл:Linq для запроса XML возвращает нуль

<?xml version="1.0" encoding="utf-8"?> 
<tmx version="1.4"> 
    <header/> 
    <body> 
    <tu> 
     <tuv lang="en"> 
     <seg>Hello?</seg> 
     </tuv> 
     <tuv lang="es"> 
     <seg>¿Diga?</seg> 
     </tuv> 
    </tu> 
    </body> 
</tmx> 

И я пытаюсь использовать этот код, чтобы извлечь содержимое первого <seg> тега:

root.Elements("tuv") 
    .Where(e => e.Attribute("lang").Value.Equals("en")) 
    .Select(e => e.Elements("seg")) 
    .SingleOrDefault() 
    .Where(d => d.Value.Equals(originalText)) 
    .SingleOrDefault() 
    .Value; 

originaltext равно «Привет?» в этом случае. Однако полученный результат равен нулю. Я предполагаю, что мой запрос linq неверен. Может ли кто-нибудь дать мне подсказку о том, как правильно писать этот запрос? Большое спасибо!

+3

Поскольку 'root' не имеет Элемент «Тув». –

+1

Действительно - вы можете использовать 'Descendants'. Вы также можете упростить свой код с помощью '==' вместо вызова 'Equals', например. 'e.Attribute (" lang "). Значение ==" en "'. Я также * настоятельно рекомендую использовать один оператор LINQ (т. Е. Вызов метода) для каждой строки - выложите свой код вертикально, и его будет намного легче читать. Затем «SingleOrDefault» возвращает одно значение ... после этого вы не хотите использовать 'Where'. –

+0

Спасибо за ваши комментарии! – Arturo

ответ

2

Функция Elements возвращает коллекцию прямых дочерних элементов root. Вы должны использовать метод Descendants, который возвращает коллекцию всех элементов-потомков.

root.Descendants("tuv").Where(e => e.Attribute("lang").Value == "en") 
         .Select(e => e.Elements("seg")).SingleOrDefault() 
         .Where(d => d.Value == originalText).SingleOrDefault().Value 
+0

Спасибо вам большое! Это то, что я искал. Так что Elements не работал, потому что «тув» не является прямым ребенком ... Я не знал, что он так работает ... мне плохо. : S – Arturo

1

Если вы хотите, чтобы выбрать первый элемент "сегмы", сделать это

var xDoc = XDocument.Parse(File.ReadAllText(@"C:\YourDirectory\sample.xml")); 

var firstSeg = xDoc.Descendants("seg").First(); 

код для удовлетворения требований OP в комментариях

var seg = xDoc.Descendants("tuv") 
       .First(tuv => tuv.Attribute("lang").Value == "en") 
       .Element("seg") 
       .Value; 
+0

Спасибо, но это будет работать только для этого примера. Извините за недопонимание. – Arturo

+1

@Arturo, пожалуйста, можете ли вы четко указать, каковы ваши критерии отбора? –

+0

Выберите содержимое внутри с атрибутом "lang" == "en". Ответ, данный Лукасом Кабртом, сработал. В любом случае, спасибо :). – Arturo

Смежные вопросы