2015-07-14 15 views
5

Mam mały problem z odczytaniem informacji z pliku xml ...Czytaj xml z pliku

Plik przekazany do mnie ma tysiące linii. Interesowało mnie tylko 300 - 400 z tych linii. Nie muszę zapisywać żadnych danych z powrotem do xml, gdy użytkownik zakończy swoją operację, a dane do odczytania można przechowywać w postaci List<string>.

Znalazłem rozwiązania w Internecie za pomocą XmlTextReader, aby odczytać dane. Więc nie musiałbym tworzyć klasy i używać Serializera. Ale wygląda na to, że użyłem niewłaściwego kodu XmlTextReader. Może mi pomóc ...

ten sposób xml wygląda następująco:

<?xml version="1.0" encoding="utf-8"?> 
<ProjectConfiguration xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <ProjectLists xmlns="..."> 
    <ProjectList> 
    ... // not interested in this data 
    </ProjectList> 
    <ProjectList> 
    <ListNode> 
    <Name>Test_Environment</Name> 
    <Children> 
     <ListNode> 
     <Name>yyy</Name> 
     <Children> 
      <ListNode> 
      <Name>205 (ST)</Name> 
      <Children> 
       <ListNode> 
       <Name>098-0031</Name> 
       <Children /> 
       </ListNode> 
       <ListNode> 
       <Name>098-0032</Name> 
       <Children /> 
       </ListNode> 
       //more ListNodes... 
      </Children> 
      </ListNode> 
      <ListNode> 
      <Name>old</Name> 
      <Children> 
       <ListNode> 
       <Name>W098-32</Name> 
       <Children /> 
       </ListNode> 
      </Children> 
      </ListNode> 
     </Children> 
     </ListNode> 
     <ListNode> 
     <Name>xxx</Name> 
     <Children /> 
     </ListNode> 
     <ListNode> 
     <Name>098-0001</Name> 
     <Children /> 
     </ListNode> 
     <ListNode> 
     <Name>098-0011</Name> 
     <Children /> 
     </ListNode> 
     // More List Nodes 
    </Children> 
    </ListNode> 
    <ListNode> 
    // more List Nodes 
    </ListNode> 
</ProjectList> 
<ProjectList> 
    //more uninteresting ProjectLists... 
</ProjectList> 

Jestem zainteresowany tylko w Value najbardziej wewnętrzne elementy imię (pierwsze dwa byłyby "098-0031" i "098-0032").

I to jest mój kod:

while (reader.Read()) { 
      switch (reader.NodeType) { 
       case XmlNodeType.Element: 
        { 
         if (reader.Name == "Name") { 
          reader.Read(); 
          if (reader.Value == "Test_Environment") { 
           reader.ReadToDescendant("Children"); 
           if (reader.Name == "Children") { 
            reader.ReadToDescendant("Children"); 

           } 
          } 
         } 
        } 
        break; 
      } 
     } 

Ale warunek jest spełniony reader.Name == "Children" nigdy ... Czy ktoś może mi wyjaśnić dlaczego. A może pokaże mi łatwy sposób przechowywania tych wartości w List<string>? Z góry dziękuję!

EDYCJA: Edytowałem xml. Przepraszam za to, ale jest naprawdę ciężko, aby filtrować unnecassary części mylące z mojego xml ...

+0

Czy można używać innych, takich jak 'Linq2XML'? –

+0

@SkyFang Absolutnie możliwe – user3596113

Odpowiedz

2
static void GetMostInnerName() 
{ 
    string xml = @"<ProjectConfiguration xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xsi=""http://www.w3.org/2001/XMLSchema-instance""> 
<ProjectLists> 
<ProjectList> 
<ListNode> 
<Name>Test_Environment</Name> 
<Children> 
<ListNode> 
<Name>yyy</Name> 
<Children> 
<ListNode> 
<Name>205 (ST)</Name> 
<Children> 
<ListNode> 
<Name>098-0031</Name> 
<Children /> 
</ListNode> 
<ListNode> 
<Name>098-0032</Name> 
<Children /> 
</ListNode> 
</Children> 
</ListNode> 
<ListNode> 
<Name>old</Name> 
<Children> 
    <ListNode> 
    <Name>W098-32</Name> 
    <Children /> 
    </ListNode> 
</Children> 
</ListNode> 
</Children> 
</ListNode> 
<ListNode> 
<Name>xxx</Name> 
<Children> 
<ListNode> 
<Name>098-0001</Name> 
<Children /> 
</ListNode> 
<ListNode> 
<Name>098-0011</Name> 
<Children /> 
</ListNode> 
</Children> 
</ListNode> 
// more List Nodes 
</Children> 
</ListNode> 
</ProjectList></ProjectLists> 
</ProjectConfiguration>"; 
    XElement root = XElement.Parse(xml).Element("ProjectLists"); 
    //var xmlns = root.GetDefaultNamespace(); 
    //Console.WriteLine(xmlns); 
    var eles = root.Elements("ProjectList").SelectMany(x => x.Elements("ListNode")); 
    List<string> list = new List<string>(); 
    foreach (var ele in eles) 
    { 
     Loop(ele, list); 
    } 
    list.ForEach(x => 
    { 
     Console.WriteLine(x); 
    }); 
} 
static void Loop(XElement ele, List<string> list) 
{ 
    var child = ele.Element("Children"); 
    if (child != null && child.HasElements) 
    { 
     foreach (var e in child.Elements("ListNode")) 
     { 
      Loop(e, list); 
     } 
    } 
    else 
    { 
     list.Add(ele.Element("Name").Value); 
    } 
} 

Ponieważ xml ma wiele węzeł jak ProjectList, więc użyłem SelectMany tutaj, i dodam root elementu mieć test, ostatnie wyjście jest

098-0031 
098-0032 
W098-32 
098-0001 
098-0011 
+0

Dziękuję, ale 'eles' jest pusty dla mnie – user3596113

+0

Tak, powinieneś użyć' root.Element (xxx) .Element (yyy).Elementy ("ProjectList") ', ponieważ nie znam twojej struktury drzewa –

+0

Dobra, zredagowałem mój Xml. Przepraszam za to ... – user3596113

0

To może pomóc? :)

   string path = @"path.xml"; 

        if(File.Exists(path)){ 
       XmlTextReader reader = new XmlTextReader(path); 

       Console.WriteLine(""); 
       while (reader.Read()) 
       { 
        switch (reader.NodeType) 
        { 

         case XmlNodeType.Element: 
          Console.Write("<" + reader.Name); 
          Console.WriteLine(">"); 
          break; 

         case XmlNodeType.Text: 
          Console.WriteLine(reader.Value); 
          break; 
         case XmlNodeType.EndElement: 
          Console.Write("</" + reader.Name); 
          Console.WriteLine(">"); 
          break; 
        } 
       } 
       Console.ReadLine(); 
        }else{ 
         Console.WriteLine("Error file not found"); 
        } 
0

Co to za język w? Przechodzisz przez XML podobnie jak JSON, używając tagów.

0

Zastosowanie LinqToXml

var xDocument = XDocument.Parse("yourXmlString"); 
     XNamespace ns = xDocument.Root.GetDefaultNamespace(); 
     var result = (from e in xDocument 
          .Descendants(ns + "ListNode").Descendants(ns + "Children") 
          .Descendants(ns + "ListNode").Descendants(ns + "Children") 
          .Descendants(ns + "ListNode").Descendants(ns + "Children") 
          .Descendants(ns + "ListNode") 
          select e.Element(ns + "Name").Value).ToList(); 
+0

Dziękuję bardzo za pomoc. Dlaczego w pierwszym wierszu występuje wyjątek XmlException (nieprawidłowe dane w wierszu 1 pozycja 1), podczas gdy ten nie robi: 'Czytnik XmlTextReader = nowy XmlTextReader (" MyXmlString ");'? Moja pierwsza linia wygląda następująco: '' – user3596113

+0

@ user3596113 Użyj '\\' 'przed podwójnym cudzysłowem jako' ' –

+0

Jeśli chcesz aby użyć twardego zakodowanego łańcucha XML, użyj back-slash przed podwójnym cudzysłowem jako '' inaczej nie ma potrzeby, jeśli dostajesz z serwera –

1
private static void FillNames(XElement container, List<string> result) 
{ 
    XElement[] listNodes = container.Elements("ListNode").ToArray(); 
    if (!listNodes.Any()) 
     return; 

    foreach (XElement listNode in listNodes) 
    { 
     XElement nameElement = listNode.Element("Name"); 
     if (nameElement == null) 
      continue; 

     XElement childrenElement = listNode.Element("Children"); 
     if (childrenElement == null) 
      continue; 

     if (!childrenElement.HasElements) 
      result.Add(nameElement.Value); 
     else 
      FillNames(childrenElement, result); 
    } 
} 

static void Main(string[] args) 
{ 
    var result = new List<string>(); 

    string xml = Resources.Xml; // TODO: put your xml here 

    XDocument doc = XDocument.Parse(xml); 
    if (doc.Root == null) 
     return; 

    XElement[] projects = doc.Root.Elements("ProjectList").ToArray(); 

    foreach (XElement project in projects) 
     FillNames(project, result); 
}