2016-04-22 20 views
2

Ich habe versucht, Text aus einer Textdatei zu extrahieren, wenn sie nicht zwischen einem "<>" sind. Gleichzeitig möchte ich, dass die extrahierten Wörter in einer neuen Zeile gedruckt werden.Wie extrahiere ich Text zwischen "<>"

Das ist die Frage: Write a program that extracts from an XML file the text only (without the tags)

Probe Input: <?xml version="1.0"><student><name>Peter</name><age>21</age><interests count="3"><interest>Games</interest><interest>C#</interest>

gewünschte Ausgabe:

Peter 21 Games C# Java

mein Stromeingang ist wie folgt:

Peter 

21 


Games 

C# 

Java 

Dazwischen liegen Leerzeilen.

So sieht mein Code im Moment aus. Jede Hilfe wäre willkommen! Und wenn Sie sich wundern, ist dies Selbststudium-Hausaufgaben. Also brauche ich diese Hand nicht. Ich betrüge nicht.

using System; 
    using System.Collections.Generic; 
    using System.IO; 
    using System.Text; 

    namespace Chapter_15_Question_10 
    { 
     class Program 
     { 
    static void Main(string[] args) 
    { 
     Console.WriteLine("This app extracts the words not in tags"); 

     StreamReader reader = new StreamReader(
      @"C:\Users\Nate\Documents\Visual Studio 2015\Projects\Chapter 15\Chapter 15 Question 10\Chapter 15 Question 10\TextFile1.txt"); 

     StringBuilder sb = new StringBuilder(); 

     using (reader) 
     { 
      string line = reader.ReadToEnd(); 
      bool isOpen = false; 
      for (int i = 1; i < line.Length; i++) 
      { 

       if (line[i-1] == '<') 
       { 
        isOpen = true; 
       } 

       if (line[i-1] == '>') 
       { 
        isOpen = false; 
       } 

       if (isOpen) 
       { 
        continue; 
       } 

       if (!(isOpen) && (line[i] != '<')) 
        Console.Write(line[i]); 
       if(line[i] == '<') 
        Console.WriteLine(); 
      } 
     } 
    } 
} 

}

+12

Sie können eine 'xml deserialization' tun, würde Ihre Leben viel einfacher, sieht aus wie Hausaufgaben, also sollten Sie den Rest selbst tun :) –

+2

Um weiter zu machen, was AD.Net sagte, hier ist ein hilfreicher MSDN Artikel für Sie: [XML Processing Options] (https://msdn.microsoft .com/de-de/library/bb669131 (v = vs.110) .aspx) –

+0

Benötigt die Lösung die manuelle Syntaxanalyse des XML-Codes oder können Sie bereits vorhandene Tools verwenden? – SpaceghostAli

Antwort

1

Versuchen Sie nicht durch das Lesen Zeile für Zeile das XML selbst zu analysieren und die Trennzeichen Parsen. .NET bietet eine Reihe von Klassen, mit denen Sie XML lesen können.

Was Sie suchen, sind Textknoten.

diese XML Unter der Annahme,

var xml = "<?xml version=\"1.0\"?><student><name>Peter</name><age>21</age><interests count=\"3\"><interest>Games</interest><interest>C#</interest></interests></student>"; 

Diese Version verwendet die neueren System.Xml.Linq Namespace, wo Sie verwenden Linq Abfragen aromatisiert Ihre XML zu lesen.

var doc = XDocument.Parse(xml); // Use XDocument.Load instead of parse to read from a file 
foreach (var text in doc.DescendantNodes().Where(n => n.NodeType == System.Xml.XmlNodeType.Text)) 
{ 
    Console.WriteLine(text); 
} 

Während diese Version die System.Xml Namespace verwendet, wo Sie XPath verwenden können, um eine Abfrage zu schreiben.

var doc = new XmlDocument(); 
doc.LoadXml(xml); // Use doc.Load to read from a file 
foreach (XmlNode text in doc.SelectNodes("//text()")) 
{ 
    Console.WriteLine(text.Value); 
} 
+0

Der einzige Grund, warum ich diese Methode verwende, ist, weil ich noch lernen muss, Linq XML selbst ausgesetzt gewesen. Diese Hausaufgabe war im Kapitel Umgang mit Textdateien. Ich hätte das deutlicher machen sollen! Mein Fehler. hehe – Nate

+0

Die zweite Version, die XmlDocument verwendet, verwendet Linq nicht, aber es verwendet das ursprüngliche XmlDocument. Wenn Ihre Hausaufgaben angeben, dass Sie die Xml-Klassen überhaupt nicht verwenden sollen, ist das etwas anderes. –

0

Während ich mit anderen einverstanden bin, sollten Sie eine der .NET XML-Klassen verwenden, ich nehme an, dies ist Hausaufgaben und vielleicht will Ihr Lehrer Sie nicht. Also hier ist der Code, geändert:

for (int i = 0; i < line.Length; i++) { 
    if (line[i] == '<') { 
     isOpen = true; 
    } 
    else if (line[i] == '>') { 
     isOpen = false; 
    } 
    else if (!isOpen) { 
     Console.Write(line[i]); 
     if (i < line.length - 1 && '<' == line[i+1]) { 
      Console.WriteLine(); 
     } 
    } 
} 
+0

Zeile [i + 1] könnte geben und Index außerhalb des Bereichs – Paparazzi

+0

@Paparazzi Ja, ich dachte daran, aber angenommen, dass die XML wäre gut formatiert und immer in einem schließenden Tag enden. Aber ich werde reparieren. Dieser Code ist nicht sehr robust und sollte nicht in der "realen Welt" verwendet werden, aber da es sich um Hausaufgaben handelt, habe ich nur das angesprochen, was in der Frage gegeben wurde. –

0

Dies ist eine perfekte Anwendung für Regex:

using System; 
using System.Text.RegularExpressions; 

namespace RegexTest 
{ 
    class Program 
    { 
     static void Main(string[] args) { 
      string pattern = @"(?<=>)[^<]+(?=<)"; 
      Regex rgx = new Regex(pattern, RegexOptions.IgnoreCase); 
      string example = @"<?xml version=""1.0""><student><name>Peter</name><age>21</age><interests count=""3""><interest>Games</interest><interest>C#</interest>"; 
      MatchCollection results = rgx.Matches(example); 
      foreach (Match m in results) 
      { 
       Console.WriteLine(m.Value); 
      } 
     } 
    } 
} 

Ergebnisse:

Peter 
21 
Games 
C# 

in jeden Text zurück, die zwischen > und < , solange mindestens ein Zeichen vorhanden ist.

0

Ich habe die gleiche Hausaufgabe vor ein paar Jahren gelöst. Also, meine frühere Lösung sieht im Moment nicht so gut aus.Wie die Idee ist, „manuell“ Textanalyse ausüben konnte ich mit mehr Einsatz von String-Operationen den folgenden Ansatz vorschlagen:

 using (reader) 
     { 
      var text = reader.ReadToEnd(); 

      // Text is found between > and < tags 
      for (int i = 0; i < text.Length - 1; i++) 
      { 
       // Find first and last index of the substring to be extracted 
       if (text[i] == '>' && text[i + 1] != '<') 
       { 
        int textFirstIndex = i + 1; 

        // Handle border case 
        if (textFirstIndex == text.Length - 1) 
        { 
         sb.Append(text.Substring(textFirstIndex, 1)); 
         break; 
        } 

        int textLastIndex = text.IndexOf('<', textFirstIndex + 1); 

        // Extract substring 
        sb.AppendLine(text.Substring(textFirstIndex, textLastIndex - textFirstIndex)); 
        i = textLastIndex; 
       } 
      } 
     } 

     Console.WriteLine(sb.ToString().TrimEnd()); 

ich betonen, dass dies nicht die optimale Lösung, aber es ist für pädagogische Zwecke wie diese .

0

Wenn Sie sich die Mühe nehmen würde, es zu verfolgen
die Sequenz

>< 

wird eine Zeilenvorschub jedes Mal verursachen

bool writeON = false; 
StringBuilder sb = new StringBuilder(); 
foreach (char c in line) 
{ 
    if (c == '>') 
     writeON = true; 
    else if (c == '<') 
    { 
     writeON = false; 
     if (sb.Length > 0) 
      Debug.WriteLine(sb.ToString()); 
     sb.Clear(); 
    } 
    else if (writeON) 
     sb.Append(c); 
} 
Debug.WriteLine("ddonce"); 
Verwandte Themen