2016-04-06 5 views
2

Ich versuche, Informationen aus mehreren XML-Dateien zu sammeln und diese Informationen in einer einzigartigen XML-Datei mit XsltXSLT: Sammeln und Zusammenführen von Informationen aus mehreren Dateien

Hier ist meine ursprüngliche XML-Datei zusammenführen:

<?xml version="1.0" encoding="UTF-8"?> 
<objects> 
    <object> 
     <class>Class1</class> 
     <attribute name="name" value="object1"/> 
     <attribute name="id" value="1"/> 
    </object> 
    <object> 
     <class>Class1</class> 
     <attribute name="name" value="object2"/> 
     <attribute name="id" value="2"/> 
    </object> 
    <object> 
     <class>Class2</class> 
     <attribute name="name" value="object3"/> 
     <attribute name="id" value="3"/> 
    </object> 
</objects> 

ich habe eine zweite xML-Datei (res.xml) bekam:

<?xml version="1.0" encoding="UTF-8"?> 
<resources> 
    <lang id="1">localizedObject1</lang> 
</resources> 

ich eine dritte xML-Datei haben (res2.xml):

<?xml version="1.0" encoding="UTF-8"?> 
<resources> 
    <lang id="1">localizedObjectDesc1</lang> 
</resources> 

Dies ist das Ergebnis, das ich erhalten möchte:

<?xml version="1.0" encoding="UTF-8"?> 
<objects> 
    <object> 
     <class>Class1</class> 
     <attribute name="name" value="object1"/> 
     <attribute name="id" value="1"/> 
     <attribute name="localizedValue" value="localizedObject1"/> 
     <attribute name="localizedDescription" value="localizedObjectDesc1"/> 
    </object> 
    <object> 
     <class>Class1</class> 
     <attribute name="name" value="object2"/> 
     <attribute name="id" value="2"/> 
    </object> 
    <object> 
     <class>Class2</class> 
     <attribute name="name" value="object3"/> 
     <attribute name="id" value="3"/> 
    </object> 
</objects> 

Für alle Objekte, bei denen class = Class1 und id in res.xml ist => fügen Sie ein Attribut (localizedValue). Wenn ID ist in res2.xml => ein Attribut hinzufügen localizedDescription Für alle anderen Objekte => kopieren Sie einfach den Knoten

Vielen Dank für Ihre Hilfe.

Antwort

0

Es können einfachere Wege, aber das funktioniert in Ihrem Fall gut:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
<xsl:output method="xml"/> 
<xsl:variable name="idXML" select="document('a2.xml')/resources" /> 

<xsl:template match="node()|@*"> 
    <xsl:copy> 
    <xsl:apply-templates select="node()|@*" /> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="object"> 
    <xsl:copy> 
    <xsl:apply-templates select="node()|@*" /> 
    <xsl:variable name="curValue" select="attribute[@name='id']/@value" /> 
    <xsl:if test="class = 'Class1' and $idXML/lang[@id = $curValue]"> 
     <attribute name="localizedValue" value="{$idXML/lang[@id = $curValue]/text()}"/> 
    </xsl:if> 
    </xsl:copy> 
</xsl:template> 

</xsl:stylesheet> 

Der Ausgang wie gewünscht ist. Sie können am Anfang auch weitere Dokumente als Variablen hinzufügen und auf die gleiche Weise zugreifen ($idXML/...).

+0

Danke für die Antwort! Beide Antworten (deine und Martins) haben mir geholfen, mein Problem zu lösen. Aber ich blieb bei Ihnen, da ich weniger Pflege beim Hinzufügen neuer Dateien und Verhaltensweisen hatte. – FVi

0

Vorausgesetzt, dass Sie einen XSLT 2.0 Prozessor verwenden, können Sie einen Schlüssel

<xsl:key name="ref" match="resources/lang" use="@id"/> 

definieren und es dann wie folgt verwenden:

<xsl:variable name="res-doc" select="document('res.xml')"/> 
<xsl:variable name="res-doc2" select="document('res2.xml')"/> 


<xsl:template match="object[class = 'Class1']/attribute[name = 'id']"> 
    <xsl:copy-of select="."/> 
    <xsl:apply-templates select="key('ref', value, $res-doc)"/> 
    <xsl:apply-templates select="key('ref', value, $res-doc2)" mode="desc"/> 
</xsl:template> 

<xsl:template match="resources/lang"> 
    <attribute name="localizedValue" value="{.}"/> 
</xsl:template> 

<xsl:template match="resources/lang" mode="desc"> 
    <attribute name="localizedDescription" value="{.}"/> 
</xsl:template> 

Natürlich stellen Sie sicher, die Identität Transformation Vorlage enthalten kopieren der Rest unverändert:

<xsl:template match="@* | node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@* | node()"/> 
    </xsl:copy> 
</xsl:template> 
+0

Hallo Martin, ja ich kann XSLT 2.0 benutzen. Das scheint eine recht elegante Lösung zu sein. Vielen Dank. Die Verwendung des Schlüssels xsl: führt mich jedoch zu einer anderen Frage: Wie verschmelze ich mit einer dritten Datei (die dieselbe Struktur wie die zweite hat)? Ich habe die ursprüngliche Frage bearbeitet. – FVi

+0

@FVi, Hinzufügen des anderen Dokuments ist einfach, nur wie die Elementstruktur ist die gleiche, es scheint, aber Sie wollen eine etwas andere Ausgabe ist es notwendig, einen Modus zu verwenden. Siehe die Änderung. –

Verwandte Themen