Laden...

Base64 enkodierte Datenfelder aus Xml-Datei speichern

Erstellt von CCCC vor 6 Jahren Letzter Beitrag vor 6 Jahren 2.369 Views
C
CCCC Themenstarter:in
5 Beiträge seit 2017
vor 6 Jahren
Base64 enkodierte Datenfelder aus Xml-Datei speichern

Hallo liebe Forumuser,

ich bin ganz neu im Forum aber auch in der C# Programmierung. Wie es so ist, steht man manchmal auf dem schlauch, gerade als Anfänger. 😦

Ich stehe vor der Aufgabe Base64 dekodierte Daten aus einer XML-Datei zu speichern.

Soweit habe ich es schon geschafft, ich kann das erste Dokument speichern. Funktioniert einwandfrei.

Mein Problem ist:

Ich will alle Dokumente aus der XML-Datei mit einem Klick generieren lassen. In meinem Code wird das oberste Dokument erstellt aber er sucht nicht nach weiteren Einträgen bzw. den nachfolgenden Spalten. Es ist auch immer unterschiedlich, jede XML-Datei kann unterschiedlich viele zu generierende Dokumente haben. X(

Der Dateiname wird dabei aus dem Attribut entnommen.

Kann mir da jemand helfen? 🤔

string pathBinary;
string pathXML;

pathBinary = @"\\Netzwerkpfad\";
pathXML = @"\\Netzwerkpfad\Beispiel.xml";


XmlReader xmlReader = XmlReader.Create(pathXML);
xmlReader.ReadToFollowing("DokumentenSpalte");
string dok2 = xmlReader.GetAttribute("AttributAuslesen");

int readBytes = 0;
byte[] buffer = new byte[1000];


FileStream fileStream = new FileStream(pathBinary + dok2, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Write);
BinaryWriter binaryWriter = new BinaryWriter(fileStream);


xmlReader.ReadToFollowing("BinärSpalteAuslesen");

while ((readBytes = xmlReader.ReadElementContentAsBase64(buffer, 0, 50)) > 0)
{
                
 binaryWriter.Write(buffer, 0, readBytes); 

}

fileStream.Close();
xmlReader.Close();

Vielen Dank vorab und beste Grüße.

6.911 Beiträge seit 2009
vor 6 Jahren

Hallo CCCC, willkommen im Forum,

kannst du so ein Beispiel-XML anhängen? Mir ist nicht ganz klar worum es geht, da würde mir so ein XML sicher helfen 😉

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

C
CCCC Themenstarter:in
5 Beiträge seit 2017
vor 6 Jahren

Hi gfoidl,

vielen Dank für die Begrüssung.

Habe mal eine abgespeckte Version beigefügt, die enthält 2 Testdokmente im PDF-Ausgabeformat. Natülich sind zwischen den Dokumentendaten noch weitere Daten aber das Prinzip sollte klar sein.

Vielen Dank für Deine Hilfe.

3.003 Beiträge seit 2006
vor 6 Jahren

Das angehängt Dokument ist zwar kein gültiges XML (da sind ein paar Knoten, die geschlossen, aber nicht geöffnet werden - vermutlich beim editieren passiert), aber es wird klarer, was du tun möchtest:

Aus allen Knoten "Dokument" den Inhalt des Unterknotens "Binardaten" in eine Datei mit dem Namen des Attributs "Dateiname" des Dokument-Knotens schreiben. Im Binardaten-Knoten stehen die Daten als byte-Array, base64-encoded. Richtig?

Du musst das ganze nicht auf Händen und Knien (XmlReader) machen. Mit Linq to XML sieht das so aus:


const string BASE_PATH = @"c:\temp";
const string XML_PATH = @"c:\pfad\zu\XML-Muster.xml";
const string FILENAME_ATTR = "Dateiname";
const string ELEMENT_BIN = "Binardaten";
const string ELEMENT_NAME = "Dokument";

XDocument.Load(XML_PATH).Root.Descendants(ELEMENT_NAME)
    .Where(p => p.Attribute(FILENAME_ATTR) != null && p.Element(ELEMENT_BIN) != null)
    .ToList()
    .ForEach(p => File.WriteAllBytes(Path.Combine(BASE_PATH, p.Attribute(FILENAME_ATTR).Value),
                    Convert.FromBase64String(p.Element(ELEMENT_BIN).Value)));

Also eine Zeile 😉.

LaTino
EDIT: strings als Konstanten zwecks Übersicht/Anpassbarkeit

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

C
CCCC Themenstarter:in
5 Beiträge seit 2017
vor 6 Jahren

Hallo LaTino,

ich danke dir vielmals, genau das war es woran ich seit Tagen gesessen habe, unendlichen Dank! Bei Linq To XML bin ich noch nicht angekommen.

Das war mir sehr wichtig und ich danke, dass es Leute wie dich gibt, die den Anfängern so toll unter die Arme greifen! 👍

Vielen Dank und einen schönen Feiertag!

Konnte nicht finden, wie ich das Thema als gelöst markieren kann. Kann gern als gelöst gesetzt werden.

D
985 Beiträge seit 2014
vor 6 Jahren

Der PS Abschnitt ganz am Ende von [Hinweis] Wie poste ich richtig? erklärt das 😉

C
CCCC Themenstarter:in
5 Beiträge seit 2017
vor 6 Jahren

@ Sir Rufo - Vielen Dank, habe ich glatt überlesen.

@LaTino

Ich konnte mir das fast perfekt nun nach meinen Bedürfnissen zusammenbauen, dank Deiner Hilfe!

Frage: Wir haben ja nun den Root Knotenpunkt festgelegt, kann ich da noch einen Wert aus einem übergeordnetem Knotenpunkt entnehmen? Diesen möchte ich noch ergänzend an den Dateinamen hängen oder vll. sogar einen Ordner pro Gruppenknotenpunkt anlegen, wo die Dokumente des jeweiligen Gruppenknotenpunkts gespeichert werden.

Variante 1 (p.Element(ELEMENT_SUB_NAME):

XDocument.Load(XML_PATH).Root.Descendants(ELEMENT_NAME).Where(p => p.Attribute(FILENAME_ATTR) != null && p.Element(ELEMENT_BIN) != null).ToList().ForEach(p => File.WriteAllBytes(Path.Combine(BASE_PATH, p.Element(ELEMENT_SUB_NAME) + p.Attribute(FILENAME_ATTR).Value), Convert.FromBase64String(p.Element(ELEMENT_BIN).Value)));

oder Variante 2:
Ordner anlegen mit dem Namen aus dem Übergeordnetem Knotenpunkt, wo die Dateien gespeichert werden.

Vielen Dank.

C
CCCC Themenstarter:in
5 Beiträge seit 2017
vor 6 Jahren

Hallo liebe Freunde,

ich hab mit meinem Code folgendes Porblem und finde den Fehler nicht.

Hier lade ich ein Xml-Dokument, der mehrere Hauptknotenpunkte hat. in jedem dieser Knotenpunkte gibt es unterschiedlich viele base64decodierte Dokumente. Diese sollen in jeweils separate Ordnern gespeichert werden.

Zur Zeit macht der Code folgendes:

Die Ordner werden alle richtig erstellt und es werden auch die Dokumente mit den richtigen Dokumentennamen gespeichert.
Er speichert aber ALLE Dokumente aus allen Knotenpunkten in jeden Ordner und benennt die Dokumente entsprechend der Vorgaben. Bei Beispielsweise 3 Knotenpunkten, werden ALLE Dokumente aus den 3 Knotenpunkten in alle 3 Ordner gepseichert aber halt benannt nach den Vorgaben.

Er soll aber immer aus einem Hauptknotenpunkt die Dokumente auslesen und in den dazugehörigen Ordner speichern.

Kann mir da jemand auf die Sprünge helfen. 😦

XML-Aufbau:


<Hauptknotenpunkt_1>
- <Unterknotenpunkt_1>
-- <Unterknotenpunkt_2>
--- <Unterknotenpunkt_3> (Binärknotenpunkt)

<Hauptknotenpunkt_2>
- <Unterknotenpunkt_1>
-- <Unterknotenpunkt_2>
--- <Unterknotenpunkt_3> (Binärknotenpunkt)

<Hauptknotenpunkt_3>
- <Unterknotenpunkt_1>
-- <Unterknotenpunkt_2>
--- <Unterknotenpunkt_3> (Binärknotenpunkt)

            const string BASE_PATH = @"\\Speicherpfad";
            string XML_PATH = TxtBoxXmlPfad.Text;
            const string FILENAME_ATTR = "Knotenattribut"; 
            const string ELEMENT_BIN = "Binärcode"; 
            const string ELEMENT_NAME = "Unterknotenpunkt_2"; 


            XmlDocument doc = new XmlDocument();
            doc.Load(XML_PATH);
            XmlElement root = doc.DocumentElement;


             foreach (XmlNode Hauptknotenpunkt in root.ChildNodes)
             {
                 XmlNode node = Hauptknotenpunkt.SelectSingleNode(".//Note1);
                 XmlNode node2 = Hauptknotenpunkt.SelectSingleNode(".//Note2");
                 XmlNode node3 = Hauptknotenpunkt.SelectSingleNode(".//Note3");
                 XmlNode node4 = Hauptknotenpunkt.SelectSingleNode(".//Note4");

/* Ordner erstellen für jeden Knotenpunkt */

                 DirectoryInfo info = Directory.CreateDirectory(@"\\Speicherpfad\" + node2.InnerText + "_" + node.InnerText + "_" + node3.InnerText);

                 XDocument.Load(XML_PATH).Root.Descendants(ELEMENT_NAME).Where(p => p.Attribute(FILENAME_ATTR) != null && p.Element(ELEMENT_BIN) != null).ToList().ForEach(p => File.WriteAllBytes(Path.Combine(BASE_PATH + "/" + node2.InnerText + "_" + node.InnerText + "_" + node3.InnerText, node2.InnerText + "_" + p.Attribute(FILENAME_ATTR).Value), Convert.FromBase64String(p.Element(ELEMENT_BIN).Value)));
             }

Wäre Euch für Hilfe sehr dankbar.

Vielen Dank und beste Grüße

Mr. C

3.003 Beiträge seit 2006
vor 6 Jahren

Was zum Teufel treibst du da eigentlich?

Ist dir klar, dass du das Dokument zweimal öffnest und mit verschiedenen Methoden beackerst, wovon die eine einfach mal copy&paste ist, ohne verstanden zu haben, was da passiert?

Um dein Problem zu lösen, solltest du dich erst einmal auf eine Methode festlegen. Dann sehen wir weiter.

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)