Jump to content

Xml datei mit Batch bearbeiten


Go to solution Solved by Proll012,

Recommended Posts

Hmmm ... Du machst es uns nicht einfach Dir zu helfen.  :aha2:

 

Bitte Code ausschließlich als Text posten - diesen natürlich entsprechend als Code formatieren. Das Gleiche gilt für Fehlermeldungen und Konsolen-Ausgaben, die Du vielleicht teilen möchtest.

 

Die Fehlermeldung in PowerShell sind in Deutsch und auch größtenteils auch ziemlich eindeutig. Als Erstes solltest Du Dir vielleicht anschauen, wie man die Hilfe zu den einzelnen cmdlets - speziell die Syntax - richtig liest.  Wir können Dir hier im Rahmen eines Forums nicht beibringen, wie man PowerShell-Skripte schreibt. Die Grundlagen wirst Du Dir selbst aneignen müssen.

 

Wir können aber bei konkreten Problemen/Fehlern, die Du mit selbstgeschriebenem Code hast helfen und tun das auch sehr gern. ;-)

 

Die Reihenfolge, in der ich die Hilfe oben bereits verlinkt hatte, ist quasi schon die, die grob auch schon für Deine Aufgabe passen sollte. 

In Pseudo-Code wäre es also ungefähr so:

 

- Alle XML-Dateien im gewünschten Verzeichnis ermitteln

- in einer Schleife alle gefundenen Dateien nacheinander behandeln

- - Inhalt lesen

- - gewünschte Stelle finden

- -  Inhalt der "Zelle" aufteilen

- - für jeden einzelnen Teil der aufgeteilten Zelle einen neuen Node erzeugen und dem XML hinzufügen 

- - falls gewünscht, den "alten" zusammenhängenden Teil aus dem XML entfernen

- - neuen kompletten XML-Inhalt in neue Datei oder in die Original-Datei schreiben.

 

Achja ... Du tust Dir selbst und allen anderen, die Deinen Code lesen sollen, einen riesen Gefallen, wenn Du Deinen Code so ausführlich wie möglich schreibst.  ... also die Parameter-Namen auschreiben und keine Aliasse verwenden.  :achtung::achtung::achtung: ;-)

Edited by BOfH_666
  • Like 1
Link to post

Also erstmal danke das Ihr so viel Nachsicht mit mir habt ^^ 

 

$XmlData = [xml](Get-Content C:\Users\MeinName\Desktop\DE_nv2040.xml)

#$xmlData.GetType()

$XmlData.BMECAT.T_NEW_CATALOG.PRODUCT.PRODUCT_FEATURES.FEATURE.FVALUE
ForEach-Object (FVALUE in $XmlData) 
{
   
           if (FVALUE -like '*;*')
            
 
        
 }

 

Soooo, also ich bin soweit gekommen das ich mir FVALUE Inhalte ausgeben kann. 

 

Jetzt fehlt ja noch das ForEach Object/FVALUE mit Semikolon im Inhalt -->Semikolon Löschen, und Inhalte auf neue Nodes aufteilen. Soweit ich das jetzt richtig begriffen habe. 

Da häng ich gerade n bisschen fest.   

Link to post

Darf ich fragen, wozu Du Dich ausbilden lässt?

 

Mit XML hast Du Dir aber auch gleich ein ziemlich komplexes Thema ausgesucht ....  :aha2:  ... darum mache ich auch einen großen Bogen, wenn ich kann.

 

Da Du uns nix zum "Spielen" zur Verfügung stellst, musste ich mir selbst was basteln. Ich gehe also von einer einzelnen Datei aus, die folgendermaßen aussieht:

<?xml version="1.0" encoding="UTF-8"?>
<BMECAT>
    <T_NEW_CATALOG>
        <PRODUCT>
            <PRODUCT_FEATURES>
                <FEATURE>
                    <FVALUE>XYZ; 52; green</FVALUE>
                </FEATURE>
            </PRODUCT_FEATURES>
        </PRODUCT>
    </T_NEW_CATALOG>
</BMECAT>

 

 

Der Code um in dieser Datei den Inhalt des einzigen Nodes "FVALUE" jeweils am Semikolon aufzuspalten sieht wie folgt aus:

 

$XmlData = [xml](Get-Content -Path 'C:\Users\MeinName\Desktop\DE_nv2040.xml')
$SplittedFVALUE = ($XmlData.BMECAT.T_NEW_CATALOG.PRODUCT.PRODUCT_FEATURES.FEATURE.FVALUE -split ';').trim()
foreach ($Value in $SplittedFVALUE) {
    $child = $XmlData.CreateNode("element", "FV", "")
    $child.InnerText = $Value
    $XmlData.BMECAT.T_NEW_CATALOG.PRODUCT.PRODUCT_FEATURES.FEATURE.AppendChild($child)

}
$XmlData.Save('C:\Users\MeinName\Desktop\DE_nv2040_new.xml')

 

Idealerweise versuchst Du zu verstehen, was der Code alles macht. Das hilft Dir in Zukunft ähnliche Aufgaben zu erledigen.

 

Ich gebe der neuen Datei auch einen neuen Namen, damit man ein bissl damit spielen kann und nicht immer wieder die Quell-Datei überschreibt.

 

Jetzt hast Du also eine einzelne Datei behandelt. Du hattest geschrieben, dass es sich um mehrere Dateien handelt. Dann kannst Du jetzt um das Ganze jetzt noch eine große Schleife drumrumpacken, die genau das mit jeder einzelnen gefundenen XML-Datei macht.

 

Und Dein Ausbilder darf gern erfahren, dass Du Dir Hilfe gesucht hast!!!  

  • Thanks 1
Link to post
Es ist nicht möglich, eine Methode für einen Ausdruck aufzurufen, der den NULL hat.
In Zeile:6 Zeichen:5
+     $XmlData.BMECAT.T_NEW_CATALOG.PRODUCT.PRODUCT_FEATURES.FEATURE.Ap ...
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

Hi, also erstmal danke ich dir vielmals.

Ich werde E-Commerce Kaufmann. Also an sich habe ich gar nicht so viel mir Programmieren zu tun:)

 

Ich bekomme diese Fehlermeldung, wenn ich das Skript ausführe. 

 

 

Link to post
vor 1 Minute schrieb Proll012:

Hmm, ich habe jetzt angenommen das die nicht so wichtig sind, weil der Pfad nach FVALUE, ja so richtig ist. 

Was denkst du warum die Leute nach deiner Struktur fragen. 

 

Du musst deinen Pfad abfragen. Im Skript wird jedoch ein anderer Pfad gefragt, natürlich enthält der dann keine Daten. 

Link to post
vor 3 Stunden schrieb Proll012:

So sieht das aus, ich hab den Inhalt mal lieber schwarz gemacht. 

 

Ein Bild von Code ist wirklich nicht hilfreich. :achtung: Niemand hat Lust irgendetwas abzutippen - ganz besonders, wenn es um Code geht, wo ein kleiner Tippfehler schon einen großen Syntax-Fehler darstellen kann. 

 

Der Pfad stimmt schon. Das ist nicht das Problem. Das Problem ist, dass Du davon nicht nur einen hast. :achtung::achtung::aha2:  Wenn auf dem Tisch 3 Schrauben liegen und ich Dir sage "Gib mir mal die Schraube!", fragst Du mich vermutlich "Welche?" ..... 

 

Ich hab mir wieder mal etwas für Dich aus den Fingern gesaugt ...  :aha2:

 

<?xml version="1.0" encoding="UTF-8"?>
<BMECAT>
    <T_NEW_CATALOG>
        <PRODUCT mode="new">
            <PRODUCT_FEATURES>
                <FEATURE>
                    <FNAME></FNAME>
                    <FVALUE>XYZ; 52; green </FVALUE>
                    <FORDER></FORDER>
                </FEATURE>
                <FEATURE>
                    <FNAME></FNAME>
                    <FVALUE>XYZ; 53; blue </FVALUE>
                    <FORDER></FORDER>
                </FEATURE>
                <FEATURE>
                    <FNAME></FNAME>
                    <FVALUE>XYZ; 54; yellow </FVALUE>
                    <FORDER></FORDER>
                </FEATURE>
            </PRODUCT_FEATURES>
        </PRODUCT>
    </T_NEW_CATALOG>
</BMECAT>

 

Du brauchst also eine Schleife, um jedes Vorkommen von FEATURE zu behandeln:

$XmlData = [xml](Get-Content -Path 'C:\Users\MeinName\Desktop\DE_nv2040.xml')
foreach ($Feature in ($XmlData.BMECAT.T_NEW_CATALOG.PRODUCT.PRODUCT_FEATURES).FEATURE ) {
    $SplittedFVALUE = ($Feature.FVALUE -split ';').trim()
    foreach ($Value in $SplittedFVALUE) {
        $child = $XmlData.CreateNode("element", "FV", "")
        $child.InnerText = $Value
        $Feature.AppendChild($child)
    }
}
$XmlData.Save('C:\Users\MeinName\Desktop\DE_nv2040_new.xml')

 

Ergebnis ist dann das:

 

<?xml version="1.0" encoding="UTF-8"?>
<BMECAT>
  <T_NEW_CATALOG>
    <PRODUCT mode="new">
      <PRODUCT_FEATURES>
        <FEATURE>
          <FNAME>
          </FNAME>
          <FVALUE>XYZ; 52; green </FVALUE>
          <FORDER>
          </FORDER>
          <FV>XYZ</FV>
          <FV>52</FV>
          <FV>green</FV>
        </FEATURE>
        <FEATURE>
          <FNAME>
          </FNAME>
          <FVALUE>XYZ; 53; blue </FVALUE>
          <FORDER>
          </FORDER>
          <FV>XYZ</FV>
          <FV>53</FV>
          <FV>blue</FV>
        </FEATURE>
        <FEATURE>
          <FNAME>
          </FNAME>
          <FVALUE>XYZ; 54; yellow </FVALUE>
          <FORDER>
          </FORDER>
          <FV>XYZ</FV>
          <FV>54</FV>
          <FV>yellow</FV>
        </FEATURE>
      </PRODUCT_FEATURES>
    </PRODUCT>
  </T_NEW_CATALOG>
</BMECAT>

 

Edited by BOfH_666
  • Like 1
  • Thanks 1
Link to post

Hallo BOfH_666

ich weiß gar nicht wie ich mich bei dir bedanken soll<3

<FEATURE>
          <FNAME>Länge</FNAME>
          <FVALUE>900</FVALUE>
          <FORDER>120</FORDER>
          <FVALUE_DETAILS>84241265426</FVALUE_DETAILS>
          <FV xmlns="">900</FV>
        </FEATURE>

        <FEATURE>
          <FNAME>Farbe</FNAME>
          <FVALUE>anthrazit;edelstahl</FVALUE>
          <FORDER>200</FORDER>
          <FVALUE_DETAILS>45445256525</FVALUE_DETAILS>
          <FV xmlns="">anthrazit</FV>
          <FV xmlns="">edelstahl</FV>
        </FEATURE>

das ist das Ergebnis. Ich denke <FV xmlns=""> wird hierdurch erzeugt

 [$child = $XmlData.CreateNode("element", "FV", "")] 

also müsste ich nur FV durch FVALUE ersetzen und die letzten "" Wegnehmen, dann wäre es richtig angezeigt. 

Nur wie lösche ich dann das Alte wo noch Semikolons drin sind?

Das Skript erstellt mir jetzt auch einen <FV xmlns=""> Eintrag für welche ohne ";"    :/

Und geht das, dass der neue Eintrag dann da steht wo der Alte war/ist?

 

Alles in allem bin ich dir aber so ohnehin schon <Unendlich>%</Unendlich> dankbar und wenn du an dieser Stelle genug hast. Ist das kein Problem für mich. <3

 

Link to post
vor 13 Minuten schrieb Proll012:

also müsste ich nur FV durch FVALUE ersetzen und die letzten "" Wegnehmen, dann wäre es richtig angezeigt. 

 

Also erstmal: "Probieren geht über Studieren!!"  ... was kann denn Schlimmes passieren, wenn Du es einfach ausprobierst ... im Zweifel lernst Du, dass es so eben nicht funktioniert.  :aha2:

Und dann die ganz ehrlich gemeinte Frage "Warum? Was willst Du eigentlich erreichen? Was soll das Ganze?" Ich würde davon ausgehen, dass überflüssige Nodes einfach ignoriert werden. Also wenn eine Software einen Node oder eben mehrere Nodes <FV> unterhalb von <FEATURE> erwartet, es einen existierenden Node <FVALUE> einfach ignoriert.

 

vor 19 Minuten schrieb Proll012:

Nur wie lösche ich dann das Alte wo noch Semikolons drin sind?

Wozu? Stört das? Wenn man mit .CreateNode() einen neuen Node erzeugen kann, gibt es bestimmt auch eine Methode, wie man existierende Nodes entfernen kann. ;-)

 

vor 22 Minuten schrieb Proll012:

Das Skript erstellt mir jetzt auch einen <FV xmlns=""> Eintrag für welche ohne ";"    :/

 

Wenn Du das nicht möchtest, musst Du eine Abfrage einbauen, die entweder prüft, ob ein Semikolon enthalten ist oder ob das Aufspalten am Semikolon mehr als ein Element zurückgeliefert hat. 

Hier gibt's die Doku dazu:

https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_if?view=powershell-7.1

 

vor 24 Minuten schrieb Proll012:

Und geht das, dass der neue Eintrag dann da steht wo der Alte war/ist?

 

Wie oben schon erwähnt  ... man kann existierende Nodes entfernen oder ändern und auch neue Nodes erzeugen und generell alles machen, was man gerne möchte. ;-) 

 

Wenn jetzt aber mit jeder neuen Antwort von Dir, die eigentliche Aufgabe geändert wird, fühle ich mich ehrlich gesagt verars***t und hab keine Lust mehr.  

 

... und übrigens ...

vor 30 Minuten schrieb Proll012:

<FV xmlns="">

 

Das xmlns="" ist ein XML-Attribut und sollte meiner Meinung nach standard-konforme Tools nicht stören, wenn es nicht erwartet oder gebraucht wird.

 

Hier noch ein wenig Literatur:

https://www.w3schools.com/xml/default.asp

 

https://powershellmagazine.com/2013/08/19/mastering-everyday-xml-tasks-in-powershell/

 

https://adamtheautomator.com/powershell-parse-xml/

 

https://www.heise.de/ix/artikel/Datenzugriff-506816.html

 

 

  • Like 3
Link to post

Sooo, 

Am 24.9.2021 um 13:27 schrieb BOfH_666:

Wenn jetzt aber mit jeder neuen Antwort von Dir, die eigentliche Aufgabe geändert wird, fühle ich mich ehrlich gesagt verars***t und hab keine Lust mehr.  

Das war mein eigentliches Ziel :aha2:. Ne Spaß, schätze ich muss neben PowerShell auch noch lernen wie man von Anfang an seine Frage komplett & richtig stellt. :rolleyes::lool:

Am 24.9.2021 um 13:27 schrieb BOfH_666:

Wenn Du das nicht möchtest, musst Du eine Abfrage einbauen, die entweder prüft, ob ein Semikolon enthalten ist oder ob das Aufspalten am Semikolon mehr als ein Element zurückgeliefert hat. 

Habe ich hinbekommen. ^^

 

Am 24.9.2021 um 13:27 schrieb BOfH_666:

Das xmlns="" ist ein XML-Attribut und sollte meiner Meinung nach standard-konforme Tools nicht stören, wenn es nicht erwartet oder gebraucht wird.

Dann ist ja gut, kann das einspielen leider nicht selber ausprobieren :/

Am 24.9.2021 um 13:27 schrieb BOfH_666:

Wozu? Stört das? Wenn man mit .CreateNode() einen neuen Node erzeugen kann, gibt es bestimmt auch eine Methode, wie man existierende Nodes entfernen kann. ;-)

Hierzu, habe ich viel ausprobiert uuund komme nicht weiter....:/

 

 $XmlData = [xml](Get-Content -Path 'C:\Users\MeinName\Desktop\DE_nv2040_new.xml')
       

 		foreach ($Feature in ($XmlData.BMECAT.T_NEW_CATALOG.PRODUCT.PRODUCT_FEATURES).FEATURE ) {

 $condition = $Feature.FVALUE -match ";"

		
     
		$nodes = $XmlData.SelectNodes("FVALUE['$condition']")
        foreach($node in $nodes){$node.ParentNode.RemoveChild($node)}    
}
 }
		$XmlData.Save('C:\Users\MeinName\Desktop\DE_nv2040_new.xml')

Als Beispiel nehme ich einfach mal das. Bin aber noch mehr Möglichkeiten durchgegangen, aber nichts tut. meistens bekomme ich die Rückmeldung das der den NULL hat. 

Heute Morgen, hats zumindest was anderes gelöscht, aber ich weiß nicht mehr wie ich das zusammen gefriemelt hab.

 

Edited by Proll012
Link to post

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...