mystery Napisano 23 Lipca 2010 Zgłoś Napisano 23 Lipca 2010 (edytowane) Witam. Mam plik XML, który waży 2,8GB (jest to aktualny dump polskiej Wikipedii). W tym pliku mam wyszukać dany, konkretny tytuł i zwrócić zawartość strony. W tym celu używam LINQ to XML, aby kod był przejrzysty. Wygląda to mniej więcej tak: var text = from el in StreamXmlDocument(filePath) where el.Element("title").Value.Contains(ValueToSearch) select (string)el.Element("revision").Element("text");i private IEnumerable<XElement> StreamXmlDocument(string uri) { //cheking XmlReader class with LINQ! //code made accoring to informations at MSDN website available at URL: //http://msdn.microsoft.com/en-us/library/system.xml.linq.xnode.readfrom.aspx using (XmlReader reader = XmlReader.Create(uri)) { reader.MoveToContent(); while (reader.Read()) { switch (reader.NodeType) { case XmlNodeType.Element: if (reader.Name == "page") { XElement el = XElement.ReadFrom(reader) as XElement; el.DescendantsAndSelf().Attributes().Where(n => n.IsNamespaceDeclaration).Remove(); //nie działa if (el != null) { yield return el; } } break; } } } } Jak widać kod jest łatwy i przejrzysty. Dzięki wykorzystaniu klasy XmlReader z System.XML nie wczytuję całego pliku do pamięci, poza tym kod powinien wykonywać się szybko. Problem w tym, że ów plik XML rozpoczyna się w ten sposób (zawiera atrybut namespace): <mediawiki xmlns="http://www.mediawiki.org/xml/export-0.4/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mediawiki.org/xml/export-0.4/ http://www.mediawiki.org/xml/export-0.4.xsd" version="0.4" xml:lang="pl"> Najdziwniejsze w tym wszystkim jest to, że jeżeli wywalę xmlns="http://www.mediawiki.org/xml/export-0.4/" to wszystko działa pięknie. Jednak z nim program wywala się na linii "where..." tak, jakby nie było elementu <title> w el, bądź el był null, ale tak nie jest. Dokładnie rzecz ujmując zwracany jest taki błąd: Odwołanie do obiektu nie zostało ustawione na wystąpienie obiektu. Dodatkowo gdzieś w Internecie znalazłem artykuł, w którym ktoś napisał, że to: el.DescendantsAndSelf().Attributes().Where(n => n.IsNamespaceDeclaration).Remove();Powinno usunąć wszystkie deklaracje xmlns z elementu. Niestety w moim przypadku to nie działa. Próbowałem wykorzystać klasę XmlTextReader, która jest rozszerzeniem XmlReader i zawiera pole Namespaces. Niby po ustawieniu tego pola na null powinno być OK, ale program wywalał się w innym miejscu (element text posiada atrybut xml:space="preserve" i wywala na ":"). Niestety nie działa również. Jeżeli macie jakiś pomysł to proszę o pomoc. Chodzi o to, żeby nie modyfikować pliku XML w żaden sposób. Wynika to z tego, że dump może być aktualizowany, mogą być ściągane wikipedie w różnych językach, itp. Dodam, że pracuję w środowisku .NET 3.5 (Visual Studio 2008), język C# 3.0. Jako, że nie mogę załączyć całego pliku dumpa to uczynię to z jego małym fragmentem. Cały plik można ściągnąć z plwiki dump progress on 20100629 (aktualna wersja polskiej wiki), nazwa pliku to pages-articles.xml.bz2 pozdrawiam m Edit: Znalazłem rozwiązanie: XNamespace ns = "http://www.mediawiki.org/xml/export-0.4/";var text = from el in StreamXmlDocument(filePath) where el.Element(ns+"title").Value.Contains(titleToSearch) select (string)el.Element(ns+"revision").Element(ns+"text"); test-dump-small.zip Edytowane 23 Lipca 2010 przez mystery Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach More sharing options...