Unerwünschte Elementknoten beim Kopieren
Andreas
- xsl
Hallo ( spzieller Gruss an Thomas ;-) )
Ich möchte zwei XML Dokumente vergleichen und die fehlenden Werte vom anderen übernehmen. Leider habe ich Probleme mit dem Iterieren. Die Ergebnisknoten kommen leider mehrfach vor
Rauskommen soll folgendes :
<mitarbeiter id="4">
<nachname>Huber</nachname>
<info rating="ok" info-id="338">
<!-->aus dem zweiten XML Dokument übernommen<!-->
<vertrag nr="1">Verhandlung</vertrag>
<telefon>5524</telefon>
<info rating="sehr gut" gewicht="95" grösse="1.84" statur="kräftig"/>
</mitarbeiter>
usw....
Hier das Beispiel :
Quelldatei :
<?xml version="1.0" encoding="UTF-8"?>
<mb-datenbank>
<abteilung>
<name>
IT-Abteilung
</name>
<angehoerige>
<mitarbeiter id="5">
<nachname>Meier</nachname>
<info rating="gut" info-id="334">
<vertrag>2 Jahre</vertrag>
</info>
<telefon>3421</telefon>
<info rating="gut" gewicht="80" grösse="1.85" statur="normal"/>
</mitarbeiter>
<mitarbeiter id="4">
<nachname>Huber
</nachname>
<info rating="ok" info-id="338">
</info>
<telefon>5524</telefon>
<info rating="sehr gut" gewicht="95" grösse="1.84" statur="kräftig"/>
</mitarbeiter>
<mitarbeiter id="7">
<nachname>Hinkelstein</nachname>
<info rating="ok" info-id="355">
</info>
<telefon>3456</telefon>
<info rating="ok" gewicht="73" grösse="1.88" statur="schlank"/>
</mitarbeiter>
<mitarbeiter id="9">
<nachname>Krause</nachname>
<info rating="mangelhaft" info-id="364">>
</info>
<telefon>4556</telefon>
<info rating="schlecht" gewicht="97" grösse="1.73" statur="stark untersetzt"/>
</mitarbeiter>
</angehoerige>
</abteilung>
</mb-datenbank>
*******************************************
Hier das zweite XML Dokument, von welchem die jeweiligen Vertragsknoten kopiert wird :
Name des Dokuments : test1.xml
<?xml version="1.0" encoding="UTF-8"?>
<mb-datenbank>
<abteilung>
<name>
Produktion
</name>
<angehoerige>
<mitarbeiter id="5">
<nachname>Winther</nachname>
<info rating="gut" info-id="334">
<vertrag>2 Jahre</vertrag>
</info>
<telefon>3421</telefon>
<info rating="gut" gewicht="80" grösse="1.85" statur="normal"/>
</mitarbeiter>
<mitarbeiter id="4">
<nachname>Heinz</nachname>
<info rating="ok" info-id="338">
<vertrag nr="1">Verhandlung</vertrag>
</info>
<telefon>5524</telefon>
<info rating=" gut" gewicht="86" grösse="1.83" statur="normal"/>
</mitarbeiter>
<mitarbeiter id="7">
<nachname>Kruse</nachname>
<info rating="ok" info-id="355">
<vertrag nr="2">Verhandlung</vertrag>
</info>
<telefon>3456</telefon>
<info rating="ok" gewicht="125" grösse="1.88" statur="Bierbauch"/>
</mitarbeiter>
<mitarbeiter id="9">
<nachname>Berger</nachname>
<info rating="mangelhaft" info-id="364">
<vertrag nr="3">Verhandlung</vertrag>
</info>
<telefon>4556</telefon>
<info rating="ok" gewicht="73" grösse="1.83" statur="normal"/>
</mitarbeiter>
</angehoerige>
</abteilung>
</mb-datenbank>
*************************************
Das XSL Stylesheet :
<?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"/>
<xsl:template match="@*|node()">
xsl:copy
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="//info[@info-id]">
xsl:copy
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
<xsl:if test="not(vertrag)">
<xsl:apply-templates select="document('test1.xml')//info[@info-id]/vertrag" mode="copy"/>
</xsl:if>
</xsl:template>
<xsl:template match="@*|node()" mode="copy">
xsl:copy
<xsl:copy-of select="@*|node()"/>
<xsl:apply-templates mode="copy"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Hallo,
Hallo ( spzieller Gruss an Thomas ;-) )
An welchen denn? ;-)
Ich möchte zwei XML Dokumente vergleichen und die fehlenden Werte vom anderen übernehmen. Leider habe ich Probleme mit dem Iterieren. Die Ergebnisknoten kommen leider mehrfach vor
Rauskommen soll folgendes :
<!-->aus dem zweiten XML Dokument übernommen<!-->
<vertrag nr="1">Verhandlung</vertrag>
Hier das Beispiel :
Quelldatei :
<?xml version="1.0" encoding="UTF-8"?>
<info rating="sehr gut" gewicht="95" grösse="1.84" statur="kräftig"/>
Ich würde davon abraten Umlaute im Attributnamen zu verwenden.
Außerdem verdient dieses XML nicht die Bezeichnung XML. Sinnlose Ansammlung von Elementen die keinen Zusammehang aufweisen: nimm das <info>, vollkommen unterschiedliche Verwendung mit unterschiedlichen Attributen. Aber egal, ist nur meine Meinung.
»»Leider habe ich Probleme mit dem Iterieren. Die Ergebnisknoten kommen leider mehrfach vor
Das XSL Stylesheet :
<?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"/>
<xsl:template match="@*|node()">
xsl:copy
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="//info[@info-id]">
xsl:copy
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
<xsl:if test="not(vertrag)">
<xsl:apply-templates select="document('test1.xml')//info[@info-id]/vertrag" mode="copy"/>
</xsl:if>
</xsl:template>
<xsl:template match="@*|node()" mode="copy">
xsl:copy
<xsl:copy-of select="@*|node()"/>
<xsl:apply-templates mode="copy"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Du scheinst Thomas' Votschlag aus https://forum.selfhtml.org/?t=114035&m=725695 mit meinem aus https://forum.selfhtml.org/?t=113936&m=724947 zu kombinieren.
<xsl:template match="//info[@info-id]">
xsl:copy
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
<xsl:if test="not(vertrag)">
<xsl:apply-templates select="document('test1.xml')//info[@info-id]/vertrag" mode="copy"/>
</xsl:if>
</xsl:template>
Das // ist unnötig.
Die if-Abfrage sollte im <copy> drinn stehen, sonst wird <vertag> nach <info> ausgegeben und nicht als dessen Unterlement.
"select="document('test1.xml')//info[@info-id]/vertrag" wird auf irgendeiner <info> mit @info-id zutrreffen, (meistens auf das erste wo es vorkommt), aber nicht unbedingt auf dem <info> was du brauchst.
Auf mode="copy" kannst du in diesem Fall verzeichten, du hast bereits ein Template für alles: <xsl:template match="@*|node()">
Und so sollte dein XSL aussehen:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" />
<xsl:template match="@*|node()">
xsl:copy
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="info[@info-id]">
<xsl:variable name="currentid" select="@info-id" />
xsl:copy
<xsl:apply-templates select="@*|node()"/>
<xsl:if test="not(vertrag)">
<xsl:apply-templates select="document('test1.xml')//info[@info-id = $currentid]/vertrag" />
</xsl:if>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Grüße
Thomas