chrisen
Goto Top

XML Datei per Skript ändern

Hallo zusammen,
ich habe eine Frage zur automatischen Konvertierung einer XML Datei.

Und zwar:
Wir bekommen aus unserem Warenwirtschaftssystem folgende XML Datei raus:


<?xml version="1.0" standalone="yes"?>  
<DocumentElement>
  <article>
    <ordernumber>100002</ordernumber>
    <mainnumber>100002</mainnumber>
    <name>Artikelname</name>
    <tax>19.00</tax>
    <suppliername>Hersteller</suppliername>
    <Price>0.000000</Price>
  </article>
  <article>
    <ordernumber>100005</ordernumber>
    <mainnumber>100005</mainnumber>
    <name>Artikelname</name>
    <tax>19.00</tax>
    <suppliername>Hersteller</suppliername>
    <Price>0.000000</Price>
  </article>
</DocumentElement>

Das Problem ist, dass wir für den Import in ein anderes Programm ein anderes Format benötigen:
Am Beispiel hier der Preis und Artikel.
Leider ist es nicht möglich dies direkt aus dem Warenwirtschaftssystem zu ändern.

<Root>
   <articles>
     <article>
	  <orderNumber> 100005 </orderNumber>
	  <mainNumber> 100005 </mainNumber>
	  <name>Münsterländer Aperitif 16%</name>
	  <supplierName>Feinbrennerei Sasse</supplierName>
	  <tax>19.00</tax>
	  <price>
		  <price>14.95</price>
	  </price>
      </article>
   </articles>
</Root>

Gibt es eine Möglichkeit diese Änderungen per Skript durchzuführen? Bzw. gibt es für so etwas ein Programm?
Das heißt: Automatisch (zum Beispiel) alle 5 Std. die XML Datei aus einem bestimmten Ordner holen, bearbeiten und wieder in einen bestimmten Ordner speichern.

Würde mich riesig über Antworten freuen!

Grüße,
chrisen

Content-Key: 313935

Url: https://administrator.de/contentid/313935

Printed on: April 16, 2024 at 23:04 o'clock

Mitglied: 129813
Solution 129813 Aug 30, 2016 at 08:30:44 (UTC)
Goto Top
Hi
you only need to transfrom it with XSLT
http://www.w3schools.com/xsl/xsl_intro.asp

Regards
Member: colinardo
Solution colinardo Aug 30, 2016 updated at 10:21:04 (UTC)
Goto Top
Hallo chrisen,
das ist kein Problem. Wie @129813 schreibt ist für sowas XSLT normalerweise das Mittel der Wahl, geht zwar auch per Skript aber schneller ist's mit XSLT.

Dazu erstellt du eine Datei mit folgendem Inhalt und gibst Ihr den Namen transform.xslt
<?xml version="1.0" encoding="UTF-8"?>  
<xsl:stylesheet version="1.0"  
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">  
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />  
<xsl:template match="/">  
  <root>
  <articles>
    <xsl:for-each select="DocumentElement/article">  
      <article>
	  <orderNumber><xsl:value-of select="ordernumber"/></orderNumber>  
	  <mainNumber><xsl:value-of select="mainnumber"/></mainNumber>  
	  <name><xsl:value-of select="name"/></name>  
	  <supplierName><xsl:value-of select="suppliername"/></supplierName>  
	  <tax><xsl:value-of select="tax"/></tax>  
	  <price>
		<price><xsl:value-of select="Price"/></price>  
	  </price>
      </article>
    </xsl:for-each>
    </articles>
  </root>
</xsl:template>
</xsl:stylesheet>
ACHTUNG: XSLT und XML ist casesensitive !!

Dann erstellst du dir ein Powershell-Skript mit folgendem Inhalt, die Pfade musst du natürlich anpassen.
function Transform-XML{
    param([string]$xsltfile,[string]$xmlfile,[string]$xmlfileout
    )
try{
        $xslt = New-Object system.xml.xsl.xslcompiledtransform
        $xslt.Load($xsltfile)
        $xslt.Transform($xmlfile,$xmlfileout)
    }catch{
        throw $_.Exception.Message
   }
}
Transform-XML -xsltfile 'C:\transform.xslt' -xmlfile 'C:\input.xml' -xmlfileout 'A:\output.xml'  
Skript ausführen, fertig.


XSL Transformation kann man fast mit jeder beliebigen Skriptsprache umsetzen. Das war jetzt ein Powershell Beispiel.

Hier als Ergänzung noch die VBS/VBA Variante für das XSL Stylesheet von oben, für diejenigen für die Powershell noch immer ein böhmisches Dorf sein sollte face-wink
Const XMLIN = "C:\input.xml"  
Const XMLOUT = "C:\output.xml"  
Const XSLT = "C:\transform.xslt"  
Set xmlDoc = CreateObject("Msxml2.DOMDocument.6.0")  
Set xsltDoc = CreateObject("Msxml2.DOMDocument.6.0")  
xsltDoc.async = False : xmlDoc.async = False
xmlDoc.load(XMLIN) : xsltDoc.load(XSLT)
xmlDoc.transformNodeToObject xsltDoc,xmlDoc
xmlDoc.save XMLOUT
msgbox "XML Datei wurde transformiert und liegt unter: " & XMLOUT, vbInformation  

Grüße Uwe

Falls der Beitrag gefällt, seid so nett und unterstützt mich durch eine kleine Spende / If you like my contribution please support me and donate
Member: chrisen
chrisen Aug 30, 2016 at 09:37:31 (UTC)
Goto Top
Super vielen vielen Dank!!

Es ist echt einfacher als ich gedacht hätte.

Grüße,
chrisen
Member: colinardo
colinardo Aug 30, 2016 updated at 10:21:34 (UTC)
Goto Top
Keine Ursache. Schöne Woche. face-smile

Grüße Uwe
Member: chrisen
chrisen Aug 30, 2016 at 12:03:00 (UTC)
Goto Top
Hallo collinardo,
ich habe leider noch ein kleines Problem/Frage, wenn ich das Skript ausführe:
Ich bekomme als Output Datei immer eine Datei heraus die wie folgt aussieht:

<?xml version="1.0" encoding="UTF-8"?> 
<root>
	<articles></articles>
</root>
Member: colinardo
colinardo Aug 30, 2016 updated at 12:09:55 (UTC)
Goto Top
Hast du auf Groß-Kleinschreibung im XSL-Stylesheet geachtet? Die XPath-Selectoren wie in folgender Zeile sind case sensitive, d.h. diese müssen exakt mit der Quelle übereinstimmen sonst bekommst du so solch eine Ausgabe wie bei dir
<xsl:for-each select="DocumentElement/article"> 
Ich habe mich exakt an dein obiges Quelldokument gehalten, und damit funktioniert das hier einwandfrei. Du wirst dort einfach einen kleinen Typo gemacht haben oder dein Quelldokument ist nicht gleich formatiert wie du es hier gepostet hast. Eventuell hast du aber auch das XSLT nicht im UTF8 Format gespeichert.

Grüße Uwe
Member: chrisen
chrisen Aug 30, 2016 at 12:15:16 (UTC)
Goto Top
Ja ich habe mich exakt an die Groß- und Kleinschreibung gehalten.

Meine Input Datei sieht zum Test so aus:

<?xml version="1.0" encoding="UTF-8"?>  
<DocumentElement>
  <article>
    <ordernumber>100002</ordernumber>
    <mainnumber>100002</mainnumber>
    <name>Artikelname</name>
    <tax>19.00</tax>
    <suppliername>Hersteller</suppliername>
    <Price>0.000000</Price>
  </article>
  <article>
    <ordernumber>100005</ordernumber>
    <mainnumber>100005</mainnumber>
    <name>Artikelname</name>
    <tax>19.00</tax>
    <suppliername>Hersteller</suppliername>
    <Price>0.000000</Price>
  </article>
</DocumentElement>

die XSL so:

<?xml version="1.0" encoding="UTF-8"?>  
<xsl:stylesheet version="1.0"  
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">  
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />  
<xsl:template match="/">  
  <root>
  <articles>
    <xsl:for-each select="DocumentElement/article">  
      <article>
	  <orderNumber><xsl:value-of select="ordernumber"/></orderNumber>  
	  <mainNumber><xsl:value-of select="mainnumber"/></mainNumber>  
	  <name><xsl:value-of select="name"/></name>  
	  <supplierName><xsl:value-of select="suppliername"/></supplierName>  
	  <tax><xsl:value-of select="tax"/></tax>  
	  <price>
		<price><xsl:value-of select="Price"/></price>  
	  </price>
      </article>
    </xsl:for-each>
    </articles>
  </root>
</xsl:template>
</xsl:stylesheet>
Member: colinardo
colinardo Aug 30, 2016 updated at 12:23:50 (UTC)
Goto Top
Kann ich nicht bestätigen, läuft fehlerfrei:
Ergebnis des Transforms:
<?xml version="1.0" encoding="utf-8"?>  
<root>
  <articles>
    <article>
      <orderNumber>100002</orderNumber>
      <mainNumber>100002</mainNumber>
      <name>Artikelname</name>
      <supplierName>Hersteller</supplierName>
      <tax>19.00</tax>
      <price>
        <price>0.000000</price>
      </price>
    </article>
    <article>
      <orderNumber>100005</orderNumber>
      <mainNumber>100005</mainNumber>
      <name>Artikelname</name>
      <supplierName>Hersteller</supplierName>
      <tax>19.00</tax>
      <price>
        <price>0.000000</price>
      </price>
    </article>
  </articles>
</root>
Auf welchem OS und mit welcher PS Version machst du das ganze ?

Wurde hier auf Windows 7/10 mit PS4/5 problemlos getestet.
Member: chrisen
chrisen Aug 30, 2016 updated at 12:29:29 (UTC)
Goto Top
Ich mache das mit Windows 7 und mit der PS Version 2.0. Habe es zunächst zum testen mit einem VBScript (wie netterweise oben von dir beschrieben) gemacht
Member: colinardo
colinardo Aug 30, 2016 updated at 12:35:01 (UTC)
Goto Top
Hier funktionieren beide Versionen sowohl VBS als auch das PS in PS 2.0 Umgebung.

Ich tippe auf ein Encoding-Problem auf deiner Seite. Und überprüfe deine Skripte bitte nochmal, ich hatte sie nach dem Posten nachträglich oben noch etwas optimiert, vielleicht hattest du einfach eine falsche Version kopiert.
Mitglied: 129813
129813 Aug 30, 2016 updated at 12:38:53 (UTC)
Goto Top
I did a test and here it works too, both the VBS and PS4.0.

Regards
Member: chrisen
chrisen Aug 30, 2016 at 12:43:01 (UTC)
Goto Top
Oh man. Ich hatte einen ganz kleinen Fehler im Skript in der Namensgebung beim Input...

Vielen Dank nochmal für deine Hilfe!!!