# Mehrere XML Dateien mit XSLT Mergen!



## Bruzzler69 (11. November 2010)

Hallo Leute,

ich habe folgendes Problem.

Ich habe eine Software, die generiert mir x XML Dateien.

Ich würde gerne aus diesen x XML Dateien in gewissen Zeitabständen eine einzige generieren.

Ich habe dies versucht mit xslt zu mergen nur ist das Ergebnis, dass ich bekomme leider nicht zufriedenstellend.Ich habe Dateien, welche wie folgt aussehen.
Datei a:

```
<?xml version="1.0" encoding="UTF-8"?>
<exam:Fragment Timestamp="2010-11-10T11:24:10.834+01:00" User="xxxxx" Language="de" Email="xxxxxx@xxxx.de" xmlns:exam="http://www.xxxxx.com/">

<Entry ID="USxxxxxxxx"><LocaleData Value="test" Language="de" MarkedAsDeleted="0"/></Entry>

</exam:Fragment>
```

Datei B: 
	
	
	



```
<?xml version="1.0" encoding="UTF-8"?>
<exam:Fragment Timestamp="2010-11-10T11:24:10.834+01:00" User="XXXXX" Language="de" Email="xxxx@xxxx.xx" xmlns:exam="http://www.xxx.com/">

<Entry ID="USxxxxxxxx"><LocaleData Value="Installment place not filled, saving not possible" Language="de" MarkedAsDeleted="0"/></Entry>
<Entry ID="USxxxxx2"><LocaleData Value="Fill eceipt date Data sheet" Language="de" MarkedAsDeleted="0"/></Entry>
<Entry ID="USxxxxxx"><LocaleData Value="No inst. site" Language="de" MarkedAsDeleted="0"/></Entry>

</exam:Fragment>
```

Mein Ergebnis nach benutzen verschiedenster xslt Methodiken ergibt jeweils folgendes Ergebnis.


```
<?xml version="1.0" encoding="UTF-8"?>
<exam:Fragment xmlns:exam="http://www.xxx.com/" Timestamp="2010-11-10T11:24:10.834+01:00" User="xxxxxx" Language="de" Email="xxxx.xxxx@xxxx.xx">

	<Entry ID="USxxxxxxxx"><LocaleData Value="test" Language="de" MarkedAsDeleted="0"/></Entry>


</exam:Fragment>

<exam:Fragment xmlns:exam="http://www.xxxxx.com/" Timestamp="2010-11-10T11:24:10.834+01:00" User="xxxxxx" Language="de" Email="xxxxxxx@xxxxx.xxx">

<Entry ID="USxxxxxxxx"><LocaleData Value="Installment place not filled, saving not possible" Language="de" MarkedAsDeleted="0"/></Entry>
<Entry ID="USxxxxx2"><LocaleData Value="Fill eceipt date Data sheet" Language="de" MarkedAsDeleted="0"/></Entry>
<Entry ID="USxxxxxx"><LocaleData Value="No inst. site" Language="de" MarkedAsDeleted="0"/></Entry>

</exam:Fragment>
```

Das Problem hierbei ist, dass der Teil , der sich exam:Fragment nennt immer doppelt vorkommt, aber eigentlich interessieren mich nur die Entry Teile. Diese exam Fragment soll er einfach aus der ersten Datei nehmen.

Jemand eine Idee wie ich dies realisieren könnte?


----------



## deepthroat (16. November 2010)

Hi.

Ungefähr so:

```
<xsl:template match="ns1:Fragment">
  <xsl:copy>
    <xsl:apply-templates select="@* | node()" />
    <xsl:apply-templates match="document('datei2.xml')/ns2:Fragment/node()" />
  </xsl:copy>
</xsl:template>

<xsl:template match="node() | @*">
  <xsl:copy-of select="." />
</xsl:template>
```
Ist das Absicht das die Dokumente in verschiedenen Namensräumen sind?

Gruß


----------



## Bruzzler69 (17. November 2010)

Hi Deepthroat, vielen dank für deine Antwort, leider funktioniert dies nichtmal Ansatzweise, da er schon in Zeile 1 meckert, da er wohl den Doppelpunkt nicht schluckt. Allerdings bearbeitet dein Skript auch nur 2 Dateien oder interpretiere ich das falsch?


deepthroat hat gesagt.:


> Ist das Absicht das die Dokumente in verschiedenen Namensräumen sind?


 Wie meinst du das? Sind doch identisch die x-en sind willkürlich ausgewählt, die habe ich nur zum unkenntlich machen benutzt. Will die Dateien eben mergen, so dass die aussehen wie vorher nur eben alle beiinander.


----------



## deepthroat (17. November 2010)

Hi.





Bruzzler69 hat gesagt.:


> Hi Deepthroat, vielen dank für deine Antwort, leider funktioniert dies nichtmal Ansatzweise, da er schon in Zeile 1 meckert, da er wohl den Doppelpunkt nicht schluckt.


Wer ist "er"?

Wie lautet die Fehlermeldung?

Dir ist schon bewußt, das das kein vollständiger Stylesheet ist, und das du die Namensräume noch vereinbaren mußt?


Bruzzler69 hat gesagt.:


> Allerdings bearbeitet dein Skript auch nur 2 Dateien oder interpretiere ich das falsch?


Es geht ums Prinzip. Das gleiche funktioniert auch mit mehr Dateien.


Bruzzler69 hat gesagt.:


> Wie meinst du das? Sind doch identisch die x-en sind willkürlich ausgewählt, die habe ich nur zum unkenntlich machen benutzt.


Du hast in Datei 1 für den Namensraum "http://www.xxxxx.com/" den Präfix "exam" vereinbart, in Datei 2 hast du für den Namensraum "http://www.xxx.com/" ebenfalls den Präfix "exam" vereinbart.

Namensraum "http://www.xxxxx.com/"  ist verschieden zu Namensraum "http://www.xxx.com/". Der Namensraumpräfix den du verwendest ist völlig uninteressant.

Gruß


----------



## Bruzzler69 (17. November 2010)

deepthroat hat gesagt.:


> Hi.
> Wer ist "er"?


Oxygen XML Editor



deepthroat hat gesagt.:


> Wie lautet die Fehlermeldung?
> Wer ist "er"?




```
SystemID: C:\temp\Unbenannt2.xsl
Programmname: Saxon-PE 9.2.0.3
Feherlevel: fatal
Beschreibung: XSLT Pattern syntax error at char 13 on line 12 in {exam:Fragment}:
    Undeclared namespace prefix {exam}
Anfang: 12:41
URL: http://www.w3.org/TR/xpath20/#ERRXPST0081
```


```
SystemID: C:\temp\Unbenannt2.xsl
Programmname: Saxon-PE 9.2.0.3
Feherlevel: fatal
Beschreibung: Attribute @match is not allowed on element <xsl:apply-templates>
Anfang: 15:88
URL: http://www.w3.org/TR/xslt20/#err-XTSE0090
```



deepthroat hat gesagt.:


> Dir ist schon bewußt, das das kein vollständiger Stylesheet ist, und das du die Namensräume noch vereinbaren mußt?



Das habe ich versucht, aber selbst das geht nicht er nicht. Ich habe ns1:Fragment durch exam:Fragment ersetzt.



deepthroat hat gesagt.:


> Es geht ums Prinzip. Das gleiche funktioniert auch mit mehr Dateien.


Wie würde ich dann die Dateien zum mergen angeben?



deepthroat hat gesagt.:


> Du hast in Datei 1 für den Namensraum "http://www.xxxxx.com/" den Präfix "exam" vereinbart, in Datei 2 hast du für den Namensraum "http://www.xxx.com/" ebenfalls den Präfix "exam" vereinbart.
> 
> Namensraum "http://www.xxxxx.com/"  ist verschieden zu Namensraum "http://www.xxx.com/". Der Namensraumpräfix den du verwendest ist völlig uninteressant.


Wie gesagt die x einfach ignorieren, da steht im Klartext die gleiche URL, habe die nur unkenntlich gemacht.


----------



## deepthroat (17. November 2010)

Bruzzler69 hat gesagt.:


> ```
> SystemID: C:\temp\Unbenannt2.xsl
> Programmname: Saxon-PE 9.2.0.3
> Feherlevel: fatal
> ...


Du hast den exam Namensraum-Präfix nicht im Stylesheet deklariert.

```
<xsl:stylesheet xmlns:exam="...">
...
```



Bruzzler69 hat gesagt.:


> ```
> SystemID: C:\temp\Unbenannt2.xsl
> Programmname: Saxon-PE 9.2.0.3
> Feherlevel: fatal
> ...


Offenbar verwendest du XSL 2.0. Da heißt match select.Du hast meinen Stylesheet offenbar nicht richtig übernommen bzw. irgenwo anders einen Fehler eingebaut.



Bruzzler69 hat gesagt.:


> Das habe ich versucht, aber selbst das geht nicht er nicht. Ich habe ns1:Fragment durch exam:Fragment ersetzt.


Das allein ist natürlich Unfug, du mußt dem XSL Prozessor schon beibringen wofür ns1 bzw. exam stehen soll.



Bruzzler69 hat gesagt.:


> Wie würde ich dann die Dateien zum mergen angeben?


Wie die andere auch.



Bruzzler69 hat gesagt.:


> Wie gesagt die x einfach ignorieren, da steht im Klartext die gleiche URL, habe die nur unkenntlich gemacht.


Dann war es also keine Absicht unterschiedliche Namensräume zu verwenden... Genau das war ja meine Frage.

Gruß


----------



## Bruzzler69 (17. November 2010)

He Deepthroat,

danke mal soweit, funktioniert. Aber ich hatte mal irgendwo was gelesen, dass ich als Documents auch einen ganzen ordner angeben konnte. Kann ich das irgendwie realisieren?


----------



## deepthroat (17. November 2010)

Hi.

Mit XSLT selbst kann man keine Verzeichnisse auslesen. (Es sei denn dein XSLT Prozessor bietet eine entsprechende Erweiterung)

Du könntest eine XML Datei generieren, wo du angibst welche Dateien verarbeitet werden sollen und dann verarbeitest du die angegebenen Dateien in einer Schleife.

```
<files>
  <file>a.xml</file>
  <file>b.xml</file>
</files>
```


```
<xsl:for-each select="document('files.xml')/files/file">
  ..
</xsl:for-each>
```
Es gibt auch Tools die ein Verzeichnis auslesen und ein XML Dokument davon generieren (z.B. XMLStarlet).

Gruß


----------



## Bruzzler69 (17. November 2010)

Hiho,


ich habe mal was gelesen mit : 

```
<xsl:variable name="docs" select="collection('file:///xml_files_path/?select=*.xml')"/>
 
<xsl:template match="/">
  <xsl:copy-of select="$docs"/>
</xsl:template>
```

Kann ich das nicht irgendwie anwenden hierauf? Wäre sonst sehr mühsam diess Files immer einzeln anzugeben.


----------



## deepthroat (17. November 2010)

Hi.





Bruzzler69 hat gesagt.:


> ich habe mal was gelesen mit :
> 
> ```
> <xsl:variable name="docs" select="collection('file:///xml_files_path/?select=*.xml')"/>
> ...


Das kommt drauf an ob dein XSLT Prozessor das unterstützt.


Bruzzler69 hat gesagt.:


> Wäre sonst sehr mühsam diess Files immer einzeln anzugeben.


Man kann auch andere Tools verwenden...

Gruß


----------



## Bruzzler69 (18. November 2010)

deepthroat hat gesagt.:


> Man kann auch andere Tools verwenden...



Die da wären.....*liebguck*


----------



## deepthroat (18. November 2010)

Bruzzler69 hat gesagt.:


> Die da wären.....*liebguck*


Schon mal etwas von Suchmaschinen gehört? ;-]

http://code.google.com/p/xml-dir-listing/

In irgendeine Anwendung mußt du ja deinen Stylesheet einbauen, dann kannst du da auch das  Eingabe-XML Dokument erzeugen.

Gruß


----------

