Announcement

Collapse
No announcement yet.

XML Datei zerlegen

Collapse
This topic is closed.
X
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • XML Datei zerlegen

    verwendetes Datenbanksystem: <Microsoft Management Studio>

    Hallo, ich habe eine ziemlich große xml Datei - 8GB. Sie ist wie folgends aufgebaut:
    Code:
     
     <?xml version="1.0"><collection xmlns=....> <record type="zeitung">   <id>texta </id>      <buch> abc </buch> </record > <record type="zeitung">   <id>textb </id>      <buch> def </buch> </record > <record type="zeitung">   <id>textc</id>      <buch> ghi </buch> </record > </collection>
    Wie kann ich jetzt die Datei in 4 Dateien zerlegen? Habe ich an Tolls gesucht, aber bisher nichts gefunden. Die Datensätze haben keine ids, also kann ich auch nicht sagen, von wo bis wo. Ich werde mich über jede Tipp freuen. Viele Grüße Anna

  • #2
    Willst du diese eine XML Datei in vier XML Dateien mit derselben Struktur aufteilen? Wo/wie soll aufgeteilt werden, nach "x" "record"-Elementen? Aber was hat das mit Microsoft Management Studio zu tun, mit dem man relationale Datenbanken von MS SQL Server verwaltet?

    Comment


    • #3
      Tolls??
      Das XML hat eine Struktur. In deinem Falle kannst du bsp. jeden record in x-Dateien speichern, oder auch die records zählen und dann 50% in je eine Datei.
      Dabei müssen natürlich jeweils das Rootelement (hier collection) manuell gesetzt werden (Anfang und Ende), sowie die xml Version.

      Das kann man mit jeder Programmiersprache mit wenig Aufwand machen.
      Christian

      Comment


      • #4
        Martin Honnen, Hallo, ja ich möchte dieser Datei in 4 Dateien mit derselben Struktur aufteilen. Die records haben keine ids, deshalb kann ich auch nicht sagen von bis....

        Comment


        • #5
          Christian Marquardt Christian Marquardt
          Nun weiss ich leider nicht, wie ich hier was schreoiben soll, da ich kein Informatiker bin. Deshalb recherchoiere ich, frage ....

          Comment


          • #6
            Originally posted by Anna85 View Post
            Hallo, ja ich möchte dieser Datei in 4 Dateien mit derselben Struktur aufteilen. Die records haben keine ids, deshalb kann ich auch nicht sagen von bis....
            Ist dir die Anzahl der "record"-Elemente insgesamt bekannt, soll die Aufteilung in gleichen Teilen erfolgen? Ist die Anzahl der Elemente pro neuer Datei bekannt?

            Ein Tool, um solche Aufgaben zu erledigen, ist XSLT 3 mit Unterstützung für "Streaming", da dabei solch große Dateien nur einmal gelesen werden. Ein generisches, passendes XSLT 3 Programm wäre:

            Code:
            <?xml version="1.0" encoding="UTF-8"?>
            <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="#all" version="3.0">
            
                <xsl:param name="chunk-size" as="xs:integer" select="500"/>
            
                <xsl:mode streamable="yes"/>
                <xsl:output indent="yes"/>
            
                <xsl:template match="/*">
                    <xsl:for-each-group select="*" group-adjacent="(position() - 1) idiv $chunk-size">
                        <xsl:result-document href="split-{position()}.xml">
                            <xsl:element name="{name(..)}" namespace="{namespace-uri(..)}">
                                <xsl:copy-of select="current-group()"/>
                            </xsl:element>
                        </xsl:result-document>
                    </xsl:for-each-group>
                </xsl:template>
            
            </xsl:stylesheet>
            Nachteil: XSLT 3 wird nur von Saxon 9.9 und 9.8 EE unterstützt, dafür braucht man eine Lizenz von Saxonica, es gibt aber eine "trial license". Saxon EE ist aber auch Teil von XML-IDEs wie oXygen, auch dafür gibt es eine "trial license".

            Der Code funktioniert natürlich im Grunde auch mit der open source HE Version von Saxon 9.9 oder 9.8, nur dass die traditionelle Verarbeitung in XSLT, die das gesamte Dokument in eine navigierbare Baumstruktur einliest, auf den meisten Rechnern mit einer Eingabedatei von 8 GB vermutlich am Speicher scheitert.

            Ansonsten kann man mit XmlReader/XmlWriter unter .NET oder StaX in Java oder ähnlichen APIs in anderen Programmiersprachen/Plattformen so was natürlich auch ausprogrammieren.
            Zuletzt editiert von Martin Honnen; 01.10.2019, 18:59. Reason: Erklärung hinzugefügt, dass der gepostete Code auch mit der open source Version von Saxon funktioniert, wenn der Speicher reicht, um derartig große Dateien im traditionellen Verarbeitungsmodus von XSL

            Comment


            • #7
              Ich kenne kein Tool, welches die Aufgabe erledigen könnte, zumal erstmal festgestellt werden müsste, wie groß "4" ist.
              Auch würde ich davon ausgehen, dass 8 GB nicht unbedingt auf einmal gelesen werden können

              Programmieren:
              Quelldatei öffnen und nur die Zeilen einlesen un dabei zählen.
              Anzahl duch 4 teilen
              Zieldatei anlegen, XML Header und Rootelement schreiben
              Quelldatei öffnen und die Zeilen einlesen, in die Zieldatei kopieren
              Ist man an der durch 4 geteilten Anzahl und ein /record Element ist da, dann schreiben in diese Datei beenden (Endeelement schreibeb) und neue anfangen.
              Ansonsten noch soweit lesen und kopieren bis das /record Element kommt


              Zuletzt editiert von Christian Marquardt; 01.10.2019, 12:40.
              Christian

              Comment


              • #8
                Hi, ich kenne die letzte zeile, allerdings kann ich nicht einfach durch 4 rechnen, da die Datei muss mit record beginnen und enden.
                Die Dateien müssen nicht gleich groß sein.
                Die Datei habe ich mit 010 editor geöffnet, aber man kann nicht so markieren, wie man möchte, da die Datei groß ist und sie springt von einem zu anderen Punkt.
                Ich versuche einen Script zu schreiben, oder?

                Comment


                • #9
                  da die Datei muss mit record beginnen und enden.
                  Nein das Rootelement ist "collection"
                  Christian

                  Comment


                  • #10
                    Falls Du mit Linux arbeiten kannst, könnte man die Befehle wc und split zum zählen und trennen verwenden.
                    Auf dem Server suse im Verzeichnis /var/log liegt die Datei zum zerteilen: zypper.log, ca 3,5 MB groß.
                    wc zählt die Zeilen und gibt das Ergebnis aus.
                    split zeiteilt nun in 18000 Zeilen Schritten, ohne eine Zeile selbst zu zerteilen
                    Das Ergebnis sind 2 neue Dateien mit dem zuvor gewählten Präfix im Namen und einem "durchnummerierten" Ende.
                    Code:
                    suse:/var/log # ls -l zypper.log
                    -rw-r----- 1 root root 3575813 Aug 29  2018 zypper.log
                    
                    suse:/var/log # wc -l zypper.log
                    35589 zypper.log
                    
                    suse:/var/log # split -l18000 zypper.log zyppersplit.log
                    suse:/var/log # ls -lrt zyppersplit.log*
                    -rw-r--r-- 1 root root 1833001 Oct  1 13:34 zyppersplit.logaa
                    -rw-r--r-- 1 root root 1742812 Oct  1 13:34 zyppersplit.logab
                    Gruß, defo

                    Comment


                    • #11
                      defo
                      und das XML? Die Struktur? Die Datei kann ich nach dem zerteilen einfach als XML wieder irgendwo einlesen?
                      Christian

                      Comment


                      • #12
                        Nein, meine Angaben ersparen nur das "Programmieren" einer Zerteilung.
                        Gruß, defo

                        Comment


                        • #13
                          Ich versuche einen Script zu schreiben:

                          Code:
                           EinDatei = "d:\xml zerlegen\Beispiel.xml"
                          Von = "<record>"
                          Bis = "</record>"
                          SuchName = "<leader>(.+)</leader>"
                          Set  fso = CreateObject("Scripting.FileSystemObject")
                          EinOrdner = fso.GetParentFolderName(EinDatei)

                          Comment


                          • #14
                            Ein Tag leader gab es bisher nicht, warum du im Filesystem einen Ordner suchst, wenn du sowieso den absoluten Pfad hast......Parentfolder ist
                            d:\xml zerlegen\
                            Christian

                            Comment


                            • #15
                              ja, es soll id bis id stehen:
                              Code:
                               
                                EinDatei = "d:\xml zerlegen\Beispiel.xml" Von = "<record>" Bis = "</record>" SuchName = "<leader>(.+)</leader>" Set  fso = CreateObject("Scripting.FileSystemObject") EinOrdner = fso.GetParentFolderName(EinDatei)

                              Comment

                              Working...
                              X