2016-07-21 13 views
1

Ich habe gerade begonnen, XLS für XML-zu-XML-Transformationen zu verwenden, also ist dies vielleicht eine Anfänger-Sache, aber ich kann die gewünschte Transformation nicht in einem bekommen einzelne XSLT-Iteration, und ich bin nicht in der Lage, etwas zu diesem speziellen Thema zu finden.
Hier ist, was ich habe:Kopieren eines untergeordneten Knotens in den untergeordneten Knoten des übergeordneten Geschwisters

Quelle XML:

<data> 
<a/> 
<b> 
    <b1>ID#1</b1> 
    <b2> 
    <b2_1/> 
    </b2> 
</b> 
<c> 
    <b1>ID#1</b1> 
    <b2_2/> 
</c> 
<!-- b and c nodes keep repeating with the same structure for different b1 IDs --> 
</data> 

Was ich tun muss, ist <b2_2> Knoten mit seinem Inhalt von einem <c> Knoten zu dem untergeordneten Knoten des spezifisch zu bewegen<b> Knoten - mit dem Wert b/b1 gleich dem Wert von c/b1.
Also, Bacicly, um einen Child-Knoten zu seinem Cousin-Knoten zu verschieben, wenn ihre Eltern ein bestimmtes Element mit demselben Wert teilen.

Wunschergebnis:

<data> 
<a/> 
<b> 
    <b1>ID#1</b1> 
    <b2> 
    <b2_1/> 
    <b2_2/> 
    </b2> 
</b> 
</data> 

Aktuelle XSLT:

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

<xsl:template match="b"> 
    <xsl:variable name="id1" select="b1" /> 
    <xsl:copy> 
    <xsl:apply-templates select="@* | node()"/> 
    <xsl:apply-templates select="following-sibling::c[b1=$id1]/b2_2"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="c"/> 

Dieser Code ein Teil des Jobs ist - es das Ziel <b2_2> Knoten mit dem Knoten Ziel <b> bewegt, während Reinigen des redundanten <c> Knotens.

Was ich jetzt:

<data> 
<a/> 
<b> 
    <b1>ID#1</b1> 
    <b2> 
    <b2_1/> 
    </b2> 
    <b2_2/> 
</b> 
</data> 

Ich kann sehen, wie die gewünschte Umwandlung in zwei Schritten mit zwei XSLT-Dateien zu machen, aber ich fühle mich wie die Lösung einfach und auf der Oberfläche ist. Kann den Weg nicht finden, um den Zielknoten zu dem Unterknoten zu bringen, wo er sein soll, so werden irgendwelche Tipps in der richtigen Richtung geschätzt.

Antwort

0

Wie wäre:

<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:strip-space elements="*"/> 

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

<xsl:template match="b2"> 
    <xsl:copy> 
     <xsl:apply-templates/> 
     <xsl:copy-of select="../following-sibling::c[1]/b2_2"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="c"/> 

</xsl:stylesheet> 

Oder, wenn Sie es vorziehen, von b1 Wert zu verknüpfen:

<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:strip-space elements="*"/> 

<xsl:key name="c" match="c" use="b1" /> 

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

<xsl:template match="b2"> 
    <xsl:copy> 
     <xsl:apply-templates/> 
     <xsl:copy-of select="key('c', ../b1)/b2_2"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="c"/> 

</xsl:stylesheet> 
+0

Vielen Dank für solch eine rasche Antwort! Du hast recht, ich muss die Knoten mit 'b1' verbinden. Tut mir leid, dass ich es nicht erst erklärt habe, aber 'b2' hat bereits andere Elemente als' b2_2' und dein Code löscht sie dabei. Ich habe die Frage so bearbeitet, dass dieser Punkt klarer ist. – twinchenzo

+0

Einfache Reparatur - siehe oben. –

+0

Vielen Dank, Michael, Ihre Antwort hat mich in die richtige Richtung gelenkt und nach dem Studium der Regeln von 'xsl: key' Verwendung habe ich Ihre angebotene Lösung erfolgreich in die eigentlichen Daten implementiert. – twinchenzo