Laden...

[gelöst] Aus mehrere XML Dateien Daten extrahieren

Erstellt von IchAJ vor 3 Jahren Letzter Beitrag vor 2 Jahren 1.060 Views
I
IchAJ Themenstarter:in
8 Beiträge seit 2021
vor 3 Jahren
[gelöst] Aus mehrere XML Dateien Daten extrahieren

Hallo,

folgende Situation:
in einem Ordner sind mehrere XML Files (>20Stück, Größe ca.: 6MB) aus diesen muss ich verschiedene Werte extrahieren.
Das habe ich über xpathDocument und Xpathnavigator versucht zu realisieren.
Grundsätzlich funktioniert es bei bis zu 14 Dateien im Ordner. Bei mehr hängt sich das Programm im Navigieren im XML File auf.
Frage: nachdem die xml Files ja immer als neue Instanz des xpathDocuments geladen werden ( jedenfalls bei mir im Code) läuft mir da der Speicher voll oder was könnte dieses Phänomen verursachen?

Danke

Gruß




Verwendetes Datenbanksystem: <bitte immer angeben>

T
2.224 Beiträge seit 2008
vor 3 Jahren

Nieman kennt oder sieht deinen Code, wie soll man dir da sagen was die Ursache ist?
Glaskugeln haben dabei auch noch nicht den erwarteten Durchbruch erreicht.
Bitte poste mal deinen Code, der das Problem verursacht.
Eigentlich sollte sich sowas ohne große Probleme auch durch debuggen finden lassen.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

I
IchAJ Themenstarter:in
8 Beiträge seit 2021
vor 3 Jahren
Code

ja hab ich nicht einstellen können da ich in Kurzarbeit war und der Code sich auf der Arbeit befand.


 private void xmleinlesen(string pfad, string diode)
        {
            
            string datname = Path.GetFileNameWithoutExtension(pfad);
            XMLS=readXml(pfad, diode);
        }

        private static List<Element> readXml(string pfad, string diode)
        {
            List<Element> data = new List<Element>();

           var xPathDoc = new XPathDocument(pfad);
            XPathNavigator navigator = xPathDoc.CreateNavigator();

            navigator.MoveToRoot();
            while (navigator.MoveToFollowing("VvExtDataExportXml", ""))
            {
                navigator.MoveToChild("DataModel", "");
                var BC = navigator.GetAttribute("Barcode","");
                navigator.MoveToChild("Object", "");
                //while( navigator.MoveToFollowing("DataModel", ""))
                // {
                int n = 0;
                var Board1 = "";
                do
                {
                    
                    if (navigator.GetAttribute("Class","")=="Board")
                    {
                        Board1 = navigator.GetAttribute("Name", "");
                    }
                    if (navigator.GetAttribute("Name","")==diode)
                      {
                        
                        n++;

                            navigator.MoveToChild("Features", "");
                        navigator.MoveToChild("Feature", "");
                        do
                        {
                            navigator.MoveToNext();
                            //navigator.MoveToFollowing("Feature", "");
                            var text = navigator.GetAttribute("Name", "");
                            if (text == "Displacement")
                            {
                                navigator.MoveToChild("Values", "");
                                navigator.MoveToChild("Value", "");
                                var text1  = navigator.GetAttribute("Name","");
                                var disx = navigator.GetAttribute("Value", "");
                                navigator.MoveToNext();
                                var text2 = navigator.GetAttribute("Name", "");
                                var disy = navigator.GetAttribute("Value", "");

                                data.Add(new Element { Barcode = (ulong.Parse(BC) + ulong.Parse(Board1) - 1).ToString(),Board = Board1, Bez = diode, VersatzX = disx, VersatzY = disy });
                             
                                break;
                            }





                        } while (n<11);


                    }
                     navigator.MoveToFollowing("Object", "");
                } while (n<10);



               
                
               
                
                
                

            }
            
            return data;
          
        }

        private void button2_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog fbd = new FolderBrowserDialog();
            fbd.RootFolder = Environment.SpecialFolder.MyComputer;
            fbd.ShowNewFolderButton = true;
            DialogResult result = fbd.ShowDialog();

            if (result == DialogResult.OK)
            {

                string pfad = fbd.SelectedPath;
                if (pfad != "")


                    
                    
                   
                {
                    int anzahl = CountFiles(pfad);
                    textBox2.Text = anzahl.ToString();

                    var dir_info_in = new DirectoryInfo(pfad);
                    foreach (var datei in dir_info_in.GetFiles("*.xml"))
                    {
                            libo1.Items.Add(datei);
                            string output_txt = "output.csv";
                            var dioden = new string[] { "U1", "U2", "U3", "U4", "U5", "U6", "U7", "U8", "U9", "U10", "U11" };
                            foreach (var d in dioden)
                            {
                                xmleinlesen(datei.FullName, d);
                                int count = 0;
                                foreach (var vs in XMLS)
                                {
                                //string ausgabe = XMLS[count].Barcode + ", Board Nr: " + XMLS[count].Board + ", " + XMLS[count].Bez + ", x: " + XMLS[count].VersatzX + "µm, y: " + XMLS[count].VersatzY + "µm\n";
                                string ausgabe = XMLS[count].Barcode + ", " + XMLS[count].Bez + ", x: " + XMLS[count].VersatzX + "µm, y: " + XMLS[count].VersatzY + "µm\n";
                                //libo1.Items.Add(ausgabe);
                                    File.AppendAllText(output_txt, ausgabe);
                                    count++;
                                textBox3.Text = count.ToString();
                                }
                            }
                        }
                }
                textBox1.Text = pfad;
            }
        }
    private static int CountFiles(string path)
    {
        DirectoryInfo di = new DirectoryInfo(path);
        return di.GetFiles("*.xml").Length;
    }
}
}

Ist für Informatiker evtl. grausam anzuschauen aber ich hab's halt nicht anders gelernt.

Danke

P
441 Beiträge seit 2014
vor 3 Jahren

Bearbeite bitte deinen Post und setze den Code in C# Code Tags, dann kann man ihn auch lesen... niemand möchte das so versuchen zu entschlüsseln.

I
IchAJ Themenstarter:in
8 Beiträge seit 2021
vor 3 Jahren

namespace XML
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        public string endung;
        //public var xPathDoc =  XPathDocument();
        public class Element
        {
            public string Barcode { get; set; }
            public string Board { get; set; }
            public string Bez { get; set; }
            public string VersatzX { get; set; }
            public string VersatzY { get; set; }
        }
        public List<Element> XMLS = new List<Element>();
        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog1 = new OpenFileDialog();

            openFileDialog1.InitialDirectory = "Desktop";
            // openFileDialog1.Filter = "Text files (*.txt)|*.txt|All files (*.*)|*.*|xml files (*.xml)";
            openFileDialog1.FilterIndex = 2;
            openFileDialog1.RestoreDirectory = true;

            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                
                string pfad = openFileDialog1.FileName.ToString();
                if (pfad != "")
                {
                    try
                    {
                       endung = Path.GetExtension(pfad);
                       string Dateiname = Path.GetFileName(pfad);
                        //LbSAP.Text = Dateiname;
                    }
                    catch
                    {
                        MessageBox.Show("Falsches Dateiformat!");
                        return;
                    }
                    
                    if (endung == ".xml")
                    {
                        var dioden = new string[] { "U1", "U2", "U3", "U4", "U5", "U6", "U7", "U8", "U9", "U10", "U11" };
                        foreach (var d in dioden)
                        {
                            xmleinlesen(pfad, d);
                            int count = 0;
                            foreach (var vs in XMLS)
                            {
                                string ausgabe = XMLS[count].Barcode + ", Board Nr: " + XMLS[count].Board + ", " + XMLS[count].Bez + ", x: " + XMLS[count].VersatzX + "µm, y: " + XMLS[count].VersatzY + "µm\n";
                                //libo1.Items.Add(ausgabe);
                                var output_txt = Path.GetFileNameWithoutExtension(pfad) + ".txt";
                                File.AppendAllText(output_txt, ausgabe);
                                count++;
                            }
                        }
                    }
                }
                textBox1.Text = pfad;
            }
            //int count = 0;
            //foreach (var vs in XMLS)
            //{
            //    string ausgabe = XMLS[count].Barcode +" |Board Nr:"+ XMLS[count].Board + " " + XMLS[count].Bez + " " + XMLS[count].VersatzX + "µm " + XMLS[count].VersatzY + "µm ";
            //    libo1.Items.Add(ausgabe);
            //    count++;
            //}
        }

        private void xmleinlesen(string pfad, string diode)
        {
            
            string datname = Path.GetFileNameWithoutExtension(pfad);
            XMLS=readXml(pfad, diode);
        }

        private static List<Element> readXml(string pfad, string diode)
        {
            List<Element> data = new List<Element>();

           var xPathDoc = new XPathDocument(pfad);
            XPathNavigator navigator = xPathDoc.CreateNavigator();

            navigator.MoveToRoot();
            while (navigator.MoveToFollowing("VvExtDataExportXml", ""))
            {
                navigator.MoveToChild("DataModel", "");
                var BC = navigator.GetAttribute("Barcode","");
                navigator.MoveToChild("Object", "");
                //while( navigator.MoveToFollowing("DataModel", ""))
                // {
                int n = 0;
                var Board1 = "";
                do
                {
                    
                    if (navigator.GetAttribute("Class","")=="Board")
                    {
                        Board1 = navigator.GetAttribute("Name", "");
                    }
                    if (navigator.GetAttribute("Name","")==diode)
                      {
                        
                        n++;

                            navigator.MoveToChild("Features", "");
                        navigator.MoveToChild("Feature", "");
                        do
                        {
                            navigator.MoveToNext();
                            //navigator.MoveToFollowing("Feature", "");
                            var text = navigator.GetAttribute("Name", "");
                            if (text == "Displacement")
                            {
                                navigator.MoveToChild("Values", "");
                                navigator.MoveToChild("Value", "");
                                var text1  = navigator.GetAttribute("Name","");
                                var disx = navigator.GetAttribute("Value", "");
                                navigator.MoveToNext();
                                var text2 = navigator.GetAttribute("Name", "");
                                var disy = navigator.GetAttribute("Value", "");

                                data.Add(new Element { Barcode = (ulong.Parse(BC) + ulong.Parse(Board1) - 1).ToString(),Board = Board1, Bez = diode, VersatzX = disx, VersatzY = disy });
                             
                                break;
                            }





                        } while (n<11);


                    }
                     navigator.MoveToFollowing("Object", "");
                } while (n<10);



               
                
               
                
                
                

            }
            
            return data;
          
        }

        private void button2_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog fbd = new FolderBrowserDialog();
            fbd.RootFolder = Environment.SpecialFolder.MyComputer;
            fbd.ShowNewFolderButton = true;
            DialogResult result = fbd.ShowDialog();

            if (result == DialogResult.OK)
            {

                string pfad = fbd.SelectedPath;
                if (pfad != "")


                    
                    
                   
                {
                    int anzahl = CountFiles(pfad);
                    textBox2.Text = anzahl.ToString();

                    var dir_info_in = new DirectoryInfo(pfad);
                    foreach (var datei in dir_info_in.GetFiles("*.xml"))
                    {
                            libo1.Items.Add(datei);
                            string output_txt = "output.csv";
                            var dioden = new string[] { "U1", "U2", "U3", "U4", "U5", "U6", "U7", "U8", "U9", "U10", "U11" };
                            foreach (var d in dioden)
                            {
                                xmleinlesen(datei.FullName, d);
                                int count = 0;
                                foreach (var vs in XMLS)
                                {
                                //string ausgabe = XMLS[count].Barcode + ", Board Nr: " + XMLS[count].Board + ", " + XMLS[count].Bez + ", x: " + XMLS[count].VersatzX + "µm, y: " + XMLS[count].VersatzY + "µm\n";
                                string ausgabe = XMLS[count].Barcode + ", " + XMLS[count].Bez + ", x: " + XMLS[count].VersatzX + "µm, y: " + XMLS[count].VersatzY + "µm\n";
                                //libo1.Items.Add(ausgabe);
                                    File.AppendAllText(output_txt, ausgabe);
                                    count++;
                                textBox3.Text = count.ToString();
                                }
                            }
                        }
                }
                textBox1.Text = pfad;
            }
        }
    private static int CountFiles(string path)
    {
        DirectoryInfo di = new DirectoryInfo(path);
        return di.GetFiles("*.xml").Length;
    }
}
}


T
2.224 Beiträge seit 2008
vor 3 Jahren

Kein wunder, dass du hängen bleibst.
Du hast dort zwei verschachtelte do...while Schleifen.
Dort kann es u.U. vorkommen, dass n nicht hochgezählt wird.
In dem Fall hängst du in einer Endlos Schleife fest.

Den Code selbst solltest du aber dringend auslagern.
Davon ist nichts testbar.
Auch gehören eigene Klassen am besten in eine eigene .cs Datei
Für das auslesen der XML Dateien würde ich mir eine eigene Xml Parser Klasse bauen.
Intern kannst du dort dann auch mit xPath arbeiten, was das ganze Schleifen verschachteln im einfachsten Fall auf einfache foreach Schleifen runterbricht.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

I
IchAJ Themenstarter:in
8 Beiträge seit 2021
vor 3 Jahren

Hallo,

Danke für die Antwort, nur zu meinem Verständnis, wenn ich mehr wie ca.:14 von den XML Files im Ordner habe kann die Verschachtelung der Do While Schleifen den Effekt haben das eine der schleifen n nicht mehr hochzählt?

Danke

4.942 Beiträge seit 2008
vor 3 Jahren

Deine innere Schleife


do
{
   // ...
   if (text == "Displacement")
  {
     // ...
     break;
  }
} while (n<11);

zählt n nicht hoch und die break-Anweisung verläßt die Schleife ja nur, wenn der passende Text gefunden wurde, d.h. andernfalls hast du eine Endlosschleife!

Und befolge dringend den Rat: Lagere den XML-Code in eine eigene Klasse (und eine eigene Datei) aus und dann schreibe dir passende Unit-Tests dazu: [Artikel] Unit-Tests: Einführung in das Unit-Testing mit VisualStudio

I
IchAJ Themenstarter:in
8 Beiträge seit 2021
vor 3 Jahren

OK,

Danke, auch wenn das ganze für mich nach Bug ausschaut denn wenn ich weniger wie 14 XML Dateien im Ordner habe klappt es wunderbar.

Werde das ganze wenn es eine Dauerhafte Anforderung des Kunden wird so realisieren wie Du es vorgeschlagen hast.

Gru? Achim

C
55 Beiträge seit 2020
vor 3 Jahren

Ich habe so den Verdacht das die XML Dateien leicht unterschiedlich aufgebaut sind und manchmal Werte vorkommen und manchmal halt nicht. Ich denke der Fehler auch schon ab einer Datei auftauchen wird und zwar dann, wenn es kein "Displacement" Wert in der XML Datei gibt. Hast du mal jede XML Datei einzeln geprüft und eingelesen?

I
IchAJ Themenstarter:in
8 Beiträge seit 2021
vor 3 Jahren

Hallo Clarasoft,

Bei den XML Daten handelt es sich um Prüfprotokolle eines AOI Systems.
Die können sich in den Values der Attribute unterscheiden (Anzahl der Kommastellen) aber vom Strukturellen Aufbau sind die alle gleich.
Den Eintrag Displacement gibt es sicher bei jedem gesuchtem Bauteil.
deswegen auch keine Abfrage ob der Eintrag überhaupt vorhanden ist.

Danke

T
2.224 Beiträge seit 2008
vor 3 Jahren

Dann hast du vielleicht auch folgendes Problem.
Du springst nur bei dem Code Block in die if Anweisung.


if (navigator.GetAttribute("Name","")==diode)

Dann du aber nicht oft genug dort reinspringen kannst, hängst du in der do..while Schleife.
Bau den Code so um, dass du keine while Schleifen brauchst.
Im Idealfall solltest du mit XPath einfach durch die Nodes laufen können.
Der Navigator scheint mir hier auch ziemlich umständlich zu sein.
Kannst du nicht ggf. per Deserialisierung die Daten auslesen?
Dann müsstest du nicht mal das Xml direkt parsen müssen.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

I
IchAJ Themenstarter:in
8 Beiträge seit 2021
vor 3 Jahren

Hallo,

brrr, langsam, erstmal mein Hintergrund:

Bin Problemorientierter SW Bastler, d.h. wenn ein Problem da ist setz ich mich hin und versuche das zu lösen. Dann ist wieder nix mehr mit Programmieren, was zur folge hat das ich immer wieder bei " wie ging die foreach schleife nochmal?" anfange.

Jetzt die Frage : Deserialisierung? interpretiere ich das richtig, wenn ich annehme das da das XML Konstruckt in einen Text umgewandelt werden kann und ich mit den ganzen String Methoden arbeiten kann?

Wäre meinem Level entgegenkommend.

aber mal noch ne frage: für die XpathDokument Klasse hab ich nur Konstruktoren gefunden, meine mich dunkel an Destruktoren zu erinnern die halt eine erstellte Instanz der Klasse wieder eliminieren.

Gibt so was für die Klasse?

Danke

P.S. Alles nur noch wegen des Lernens, hab angefangen einen XML Parser zu bauen.

T
2.224 Beiträge seit 2008
vor 3 Jahren

Mit Deserialisierung ist gemeint, dass z.B. das XML direkt zu Instanzen von Klassen umgewandelt wird.
Dafür gibt es entsprechende Klasse in .NET um dies einfach umzusetzen.
Dies spart das manuelle parsen, braucht aber etwas Know How ist im .NET Bereich aber gut dokumentiert.

Destruktoren spielen hier keine große Rolle.
In .NET gibt es dafür zum einen das Dispose Pattern über IDisposable und den Finalizer.
Das sind aber Dinge, in die du dich mal einlesen solltest.
Hat aber mit dem Problem nicht viel zu tun.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

I
IchAJ Themenstarter:in
8 Beiträge seit 2021
vor 2 Jahren

Hallo,

zum Abschluss: Habe eine neue Routine erstellt die mit XML Reader arbeitet.
Funktioniert schneller und sicherer.

Danke für die Hilfe.

Gruß Achim

Noch eine Frage: wie kann ich das Thema schließen?

16.842 Beiträge seit 2008
vor 2 Jahren

Bei uns werden keine Themen geschlossen; wir sind ein offenes Forum, in dem jeder immer antworten darf. 🙂

A
764 Beiträge seit 2007
vor 2 Jahren

Noch eine Frage: wie kann ich das Thema schließen?

Wie schon geschehen, einfach im Titel ein [gelöst] davor schreiben.