Linq в xml, когда дочерние узлы удовлетворяют определенному условию

#c# #vb.net #linq #linq-to-xml

#c# #vb.net #linq #linq-to-xml

Вопрос:

Допустим, у меня есть следующий xml:

 <Report>
<File id="1">
    <Variables>
            <Variable id="1" name="integer"> 1 </Variable>
            <Variable id="1" name="string"> x </Variable>
    </Variables>
</File>
<File id="2">
    <Variables>
            <Variable id="2" name="integer"> 1 </Variable>
            <Variable id="2" name="string"> x </Variable>
    </Variables>
</File>
<File id="3">
    <Variables>
            <Variable id="3" name="integer"> 1 </Variable>
            <Variable id="3" name="string"> y </Variable>
    </Variables>
</File>
  

Как я могу получить все файлы, в которых переменная string равна «x»?

Обратите внимание на linq в xml vb или c #, но предпочтительнее vb

Комментарии:

1. Пожалуйста, задавая вопросы, покажите, что вы пробовали / не сработало, вместо того, чтобы заполнять свой пост благодарственным / поисковым текстом, не связанным.

Ответ №1:

Предполагая, что вы уже загрузили свой XML в XDocument экземпляр, вы можете выполнить следующее:

 var files = from f in xDoc.Root.Elements("File")
            where f.Element("Variables")
                   .Elements("Variable")
                   .Any(v => (string)v.Attribute == "string" amp;amp;
                             (string)v == "x")
            select f;
  

или с использованием эквивалентного запроса на основе метода:

 var files = xDoc.Root.Elements("File")
                     .Where(f => f.Element("Variables")
                                  .Elements("Variable")
                                  .Any(v => (string)v.Attribute == "string" amp;amp;
                                            (string)v == "x"))
  

Ответ №2:

Учитывая следующий xml:

 Dim xml = <Report>
                <File id="1">
                    <Variables>
                            <Variable id="1" name="integer">1</Variable>
                            <Variable id="1" name="string">x</Variable>
                    </Variables>
                </File>
                <File id="2">
                    <Variables>
                            <Variable id="2" name="integer">1</Variable>
                            <Variable id="2" name="string">x</Variable>
                    </Variables>
                </File>
                <File id="3">
                    <Variables>
                            <Variable id="3" name="integer">1</Variable>
                            <Variable id="3" name="string">y</Variable>
                    </Variables>
                </File>
                </Report>
  

вы можете либо использовать Linq:

 Dim result = xml.<File> _
                .Where(Function(file) file.<Variables>.<Variable> _
                  .Any(Function(variable) variable.@name = "string" AndAlso 
                                          variable.Value = "x"))
  

или, короче, запрашивать узлы с помощью XPath-выражения:

 Dim doc = New XmlDocument() ' Use XmlDocument instead of XElement '
doc.LoadXml(xml.ToString())
Dim result = doc.SelectNodes("/Report/File[Variables/Variable[@name='string' and text()='x']]")