{"id":579,"date":"2010-05-19T23:07:38","date_gmt":"2010-05-19T21:07:38","guid":{"rendered":"http:\/\/dev.bratched.fr\/fr\/linq-to-xml-et-la-lecture-des-tres-gros-fichiers\/"},"modified":"2010-05-19T23:07:38","modified_gmt":"2010-05-19T21:07:38","slug":"linq-to-xml-et-la-lecture-des-tres-gros-fichiers","status":"publish","type":"post","link":"https:\/\/bratched.com\/fr\/2010\/05\/19\/linq-to-xml-et-la-lecture-des-tres-gros-fichiers\/","title":{"rendered":"LINQ to XML et la lecture des tr\u00e8s gros fichiers"},"content":{"rendered":"<p>LINQ to XML est relativement facile \u00e0 impl\u00e9menter pour lire de gros fichiers et pour requ\u00eater des fichiers XML.<br \/>\nPar exemple, consid\u00e9rons ce fichier XML :<\/p>\n<div id=\"scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:d26a3848-6354-42e0-a1c8-a4a22f0786b5\" class=\"wlWriterSmartContent\" style=\"margin: 0px;padding: 0px;float: none\">\n<pre>    &lt;?xml version=\"1.0\" encoding=\"utf-8\" ?&gt;\n    &lt;users&gt;\n        &lt;user name=\"User1\" groupid=\"4\" \/&gt;\n        &lt;user name=\"User2\" groupid=\"1\" \/&gt;\n        &lt;user name=\"User3\" groupid=\"3\" \/&gt;\n        &lt;user name=\"User4\" groupid=\"1\" \/&gt;\n        &lt;user name=\"User5\" groupid=\"1\" \/&gt;\n        &lt;user name=\"User6\" groupid=\"2\" \/&gt;\n        &lt;user name=\"User7\" groupid=\"1\" \/&gt;\n    &lt;\/users&gt;<\/pre>\n<\/div>\n<p>Supposons que vous souhaitez trouver tous les enregistrements avec groupid &gt; 2. Vous pouvez \u00eatre tent\u00e9 d\u2019impl\u00e9menter la requ\u00eate suivante :<\/p>\n<div id=\"scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:ebdcda5f-b4d9-450b-a917-932fb91b2ca8\" class=\"wlWriterSmartContent\" style=\"margin: 0px;padding: 0px;float: none\">\n<pre>    XElement doc = XElement.Load(\"users.xml\");\n    var users = from u in doc.Elements(\"user\")\n                where u.Attribute(\"groupid\") != null &amp;&amp;\n                int.Parse(u.Attribute(\"groupid\").Value) &gt; 2\n                select u;\n    Console.WriteLine(\"{0} users match query\", users.Count());\n<\/pre>\n<\/div>\n<p>Il y a un pi\u00e8ge dans cette impl\u00e9mentation. La m\u00e9thode <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.xml.linq.xelement.load.aspx\" rel=\"nofollow\">XElement.Load<\/a> va lire tout le fichier XML en m\u00e9moire avant de s\u2019ex\u00e9cuter, et ce fichier peut \u00eatre tr\u00e8s gros.<\/p>\n<p><!--more--><\/p>\n<p>Non seulement, la requ\u00eate va prendre beaucoup de temps \u00e0 s\u2019ex\u00e9cuter mais elle risque en plus de consommer tout la m\u00e9moire. Si vous avez un tr\u00e8s gros fichier XML, vous devez utiliser un syst\u00e8me de cache pour lire l\u2019essentiel plut\u00f4t que de lire une premi\u00e8re fois l\u2019ensemble du contenu en m\u00e9moire. <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.xml.xmlreader.aspx\" rel=\"nofollow\">XmlReader<\/a> est une jolie alternative pour nous permettre d\u2019avoir uniquement l\u2019enregistrement courant au lieu de l\u2019ensemble de la m\u00e9moire et ainsi consid\u00e9rablement am\u00e9liorer les performances.<\/p>\n<p>Nous commen\u00e7ons par la d\u00e9finition d\u2019une class \u201c<em>User\u201d<\/em> qui sera utilis\u00e9e pour repr\u00e9senter une simple record:<\/p>\n<div id=\"scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:cf66f4c3-5956-4f90-b501-418f51d3926c\" class=\"wlWriterSmartContent\" style=\"margin: 0px;padding: 0px;float: none\">\n<pre>    public class User \n    {\n        public string Name { get; set; }\n        public int GroupId { get; set; }\n    }<\/pre>\n<\/div>\n<p>Ensuite, nous \u00e9tendons la classe <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.xml.xmlreader.aspx\" rel=\"nofollow\">XmlReader<\/a> avec la m\u00e9thode User:<\/p>\n<div id=\"scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:534be24b-59a4-41a8-bce2-4b9b62a2a6b1\" class=\"wlWriterSmartContent\" style=\"margin: 0px;padding: 0px;float: none\">\n<pre>    public static IEnumerable&lt;User&gt; Users(this XmlReader source)\n    {\n        while (source.Read())\n        {\n            if (source.NodeType == XmlNodeType.Element &amp;&amp; \n                source.Name == \"user\")\n            {\n                int groupId;\n                int.TryParse(source.GetAttribute(\"groupid\"), out groupId);\n                yield return new User\n                {\n                    GroupId = groupId,\n                    Name = source.GetAttribute(\"name\")\n                };\n            }\n        }\n    }<\/pre>\n<\/div>\n<p>Et finalement nous ex\u00e9cutons la requ\u00eate:<\/p>\n<div id=\"scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:15625cdc-4aa2-4224-99c1-9f9cd8ad2553\" class=\"wlWriterSmartContent\" style=\"margin: 0px;padding: 0px;float: none\">\n<pre>    using (XmlReader reader = XmlReader.Create(\"users.xml\"))\n    {\n        var users = from u in reader.Users()\n                    where u.GroupId &gt; 2\n                    select u;\n        Console.WriteLine(\"{0} users match query\", users.Count());\n    }<\/pre>\n<\/div>\n<p>Conclusion: La seconde approche s\u2019ex\u00e9cute plus rapidement et utilise beaucoup moins de m\u00e9moire que la premi\u00e8re.<br \/>\nLa diff\u00e9rence est significative sur de tr\u00e8s gros fichier XML. Ainsi, si vous devez manipuler de tr\u00e8s gros fichiers XML, faites tr\u00e8s attention avec LINQ to XML.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>LINQ to XML est relativement facile \u00e0 impl\u00e9menter pour lire de gros fichiers et pour requ\u00eater des fichiers XML. Par exemple, consid\u00e9rons ce fichier XML : &lt;?xml version=\u00a0\u00bb1.0&Prime; encoding=\u00a0\u00bbutf-8&Prime; ?&gt; &lt;users&gt; &lt;user name=\u00a0\u00bbUser1&Prime; groupid=\u00a0\u00bb4&Prime; \/&gt; &lt;user name=\u00a0\u00bbUser2&Prime; groupid=\u00a0\u00bb1&Prime; \/&gt; &lt;user name=\u00a0\u00bbUser3&Prime; groupid=\u00a0\u00bb3&Prime; \/&gt; &lt;user name=\u00a0\u00bbUser4&Prime; groupid=\u00a0\u00bb1&Prime; \/&gt; &lt;user name=\u00a0\u00bbUser5&Prime; groupid=\u00a0\u00bb1&Prime; \/&gt; &lt;user name=\u00a0\u00bbUser6&Prime; groupid=\u00a0\u00bb2&Prime; \/&gt; [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[34],"tags":[48,49,50],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/bratched.com\/fr\/wp-json\/wp\/v2\/posts\/579"}],"collection":[{"href":"https:\/\/bratched.com\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/bratched.com\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/bratched.com\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/bratched.com\/fr\/wp-json\/wp\/v2\/comments?post=579"}],"version-history":[{"count":0,"href":"https:\/\/bratched.com\/fr\/wp-json\/wp\/v2\/posts\/579\/revisions"}],"wp:attachment":[{"href":"https:\/\/bratched.com\/fr\/wp-json\/wp\/v2\/media?parent=579"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/bratched.com\/fr\/wp-json\/wp\/v2\/categories?post=579"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/bratched.com\/fr\/wp-json\/wp\/v2\/tags?post=579"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}