且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

linq to XML:文档中的多个节点/值查询

更新时间:2022-11-27 10:16:40

在这种情况下,您无法查看单个后代,但是您需要分别搜索父"节点,然后查询其后代.

示例:给定文件

<br /><?xml version="1.0" encoding="utf-8" ?><br /><people><br />  <person><br />    <name>Franz</name><br />    <country>Canada</country><br />  </person><br />  <person><br />    <name>Franz</name><br />    <country>Germany</country><br />  </person><br />  <person><br />    <name>Bob</name><br />    <country>Canada</country><br />  </person><br />  <person><br />    <name>Mike</name><br />    <country>UK</country><br />  </person><br />  <person><br />    <name>Alan</name><br />    <country>Germany</country><br />  </person><br /></people>



首先,构建人"节点的列表以获取容器".然后,您可以在每个节点上进行子查询,以查找子元素.

<br />            var doc = XDocument.Load("XMLFile1.xml");<br /><br />            // select the nodes of type person<br />            var nodes = from n in doc.Descendants("person") select n;<br /><br />            // get EITHER Franz or Canada<br />            var FranzORCanada = from n in nodes<br />                                where ((from x in n.Descendants("name") where x.Value == "Franz" select x).Count() > 0)<br />                                || ((from y in n.Descendants("country") where y.Value == "Canada" select y).Count() > 0)<br />                                select n;<br /><br />            Console.WriteLine("FRANZ or CANADA");<br />            Console.WriteLine("---------------");<br />            foreach (var node in FranzORCanada)<br />            {<br />                Console.WriteLine("{0} - {1}", node.Descendants("name").First().Value, node.Descendants("country").First().Value);<br />            }<br />            Console.WriteLine();<br /><br />            // get nodes with Franz AND Canada<br />            var FranzANDCanada = from n in nodes<br />                                 where ((from x in n.Descendants("name") where x.Value == "Franz" select x).Count() > 0)<br />                                && ((from y in n.Descendants("country") where y.Value == "Canada" select y).Count() > 0)<br />                                select n;<br /><br />            Console.WriteLine("FRANZ and CANADA");<br />            Console.WriteLine("----------------");<br />            foreach (var node in FranzANDCanada)<br />            {<br />                Console.WriteLine("{0} - {1}", node.Descendants("name").First().Value, node.Descendants("country").First().Value);<br />            }<br /><br /><br />            Console.ReadKey();<br />


这将产生以下结果:

<br />FRANZ or CANADA<br />---------------<br />Franz - Canada<br />Franz - Germany<br />Bob - Canada<br /><br />FRANZ and CANADA<br />----------------<br />Franz - Canada<br />




Hi again!
Qnother question comes to my mind and since this is the best place to get an answer, I''m trying it here (hey, that''s been a compliment!).
So I can query a node/value combination from a XML file:


 public FileInfo ReadXML(FileInfo fInfo, string node, string value)            
{                                   <br /> XDocument xmlFile = XDocument.Load(fInfo.FullName);                    <br />var query = (from p in xmlFile.Descendants(node)<br />                                where p.Value.Contains(value)<br />                                 select p).ToArray();    <br />                if (query.Count() != 0)         <br />               return fInfo;           
 }




but how this should look like if I have for instance two node/value combinations I have to query for.
E.g: Name has to be Franz AND he needs to be born in Canada
Name has to be either Franz or the Person has to be born in CANADA
As always thanks in advance,
eza

(this is a double post, but I missed this forum in the first place)

In this case you cannot look at the individual descendants but you need to search the "parent" nodes individually, and then query their descendants.

Example: given the file

<br /><?xml version="1.0" encoding="utf-8" ?><br /><people><br />  <person><br />    <name>Franz</name><br />    <country>Canada</country><br />  </person><br />  <person><br />    <name>Franz</name><br />    <country>Germany</country><br />  </person><br />  <person><br />    <name>Bob</name><br />    <country>Canada</country><br />  </person><br />  <person><br />    <name>Mike</name><br />    <country>UK</country><br />  </person><br />  <person><br />    <name>Alan</name><br />    <country>Germany</country><br />  </person><br /></people>



First you build a list of the "person" node to get the ''container''. Then you can do a sub-query on each node, looking for the child elements.

<br />            var doc = XDocument.Load("XMLFile1.xml");<br /><br />            // select the nodes of type person<br />            var nodes = from n in doc.Descendants("person") select n;<br /><br />            // get EITHER Franz or Canada<br />            var FranzORCanada = from n in nodes<br />                                where ((from x in n.Descendants("name") where x.Value == "Franz" select x).Count() > 0)<br />                                || ((from y in n.Descendants("country") where y.Value == "Canada" select y).Count() > 0)<br />                                select n;<br /><br />            Console.WriteLine("FRANZ or CANADA");<br />            Console.WriteLine("---------------");<br />            foreach (var node in FranzORCanada)<br />            {<br />                Console.WriteLine("{0} - {1}", node.Descendants("name").First().Value, node.Descendants("country").First().Value);<br />            }<br />            Console.WriteLine();<br /><br />            // get nodes with Franz AND Canada<br />            var FranzANDCanada = from n in nodes<br />                                 where ((from x in n.Descendants("name") where x.Value == "Franz" select x).Count() > 0)<br />                                && ((from y in n.Descendants("country") where y.Value == "Canada" select y).Count() > 0)<br />                                select n;<br /><br />            Console.WriteLine("FRANZ and CANADA");<br />            Console.WriteLine("----------------");<br />            foreach (var node in FranzANDCanada)<br />            {<br />                Console.WriteLine("{0} - {1}", node.Descendants("name").First().Value, node.Descendants("country").First().Value);<br />            }<br /><br /><br />            Console.ReadKey();<br />


This produces the following:

<br />FRANZ or CANADA<br />---------------<br />Franz - Canada<br />Franz - Germany<br />Bob - Canada<br /><br />FRANZ and CANADA<br />----------------<br />Franz - Canada<br />