2016-06-09 9 views
0

Es fällt mir schwer, eine XSLT zu schreiben, um alle Knoten mit demselben Attributwert auf die gleiche Ebene zu verschieben.Eine verschachtelte XML mit XSLT glätten

Hier ist ein Beispiel:

<root> 
    <object Name="1"> 
     <Property Name="a1" Value="a"> 
      <Property Name="a1.1" Value="a"/> 
      <Property Name="a1.2" Value="a"> 
       <Property Name="a1.2.1" Value="a"/> 
       <Property Name="a1.2.2" Value="a"/> 
      </Property> 
     </Property> 
     <Property Name="b1" Value="b"/> 
    </object> 
</root> 

Derzeit ist es möglich, zu nisten Eigenschaften mit dem Wert ein ineinander (es gibt keine Grenze für die Menge von Knoten oder Verschachtelungsebene). Dieses Modell wird geändert, um diesen Eigenschaftstyp nur auf Objektebene zuzulassen. die wie folgt nach der Transformation (die Reihenfolge der Elemente spielt keine Rolle) aussehen sollte:

<root> 
    <object Name="1"> 
     <Property Name="a1" Value="a"/> 
     <Property Name="a1.1" Value="a"/> 
     <Property Name="a1.2" Value="a"> 
     <Property Name="a1.2.1" Value="a"/> 
     <Property Name="a1.2.2" Value="a"/> 
     <Property Name="b1" Value="b"/> 
    </object> 
</root> 

Ich habe versucht, diese Lösung in dem Beispiel ist der Hauptunterschied, dass der Knoten mit this very similar question, wird nicht kopiert werden, aber seine Werte werden verwendet. Ich konnte jedoch nicht herausfinden, wie man den gesamten Knoten kopiert.

BEARBEITEN
Das obige Beispiel ist über vereinfacht. Die Eigenschaften werden Unterelemente enthalten, die auch kopiert werden müssen

<root> 
    <object Name="1"> 
     <Property Name="a1" Value="a"> 
      <x>x1</x> 
      <y>y1</y> 
      <z>z1</z> 
      <Property Name="a1.1" Value="a"> 
       <x>x1.1</x> 
       <y>y1.1</y> 
       <z>z1.1</z> 
      </Property> 
      <Property Name="a1.2" Value="a"> 
       <x>x1.2</x> 
       <y>y1.2</y> 
       <z>z1.2</z> 
       <Property Name="a1.2.1" Value="a"> 
        <x>x1.2.1</x> 
        <y>y1.2.1</y> 
        <z>z1.2.1</z> 
       </Property> 
       <Property Name="a1.2.2" Value="a"> 
        <x>x1.2.1</x> 
        <y>y1.2.1</y> 
        <z>z1.2.1</z> 
       </Property> 
      </Property> 
     </Property> 
     <Property Name="b1" Value="b"/> 
    </object> 
</root> 

dies nach der Transformation werden sollte:

<root> 
    <object Name="1"> 
     <Property Name="a1" Value="a"> 
      <x>x1</x> 
      <y>y1</y> 
      <z>z1</z> 
     </Property> 
     <Property Name="a1.1" Value="a"> 
      <x>x1.1</x> 
      <y>y1.1</y> 
      <z>z1.1</z> 
     </Property> 
     <Property Name="a1.2" Value="a"> 
      <x>x1.2</x> 
      <y>y1.2</y> 
      <z>z1.2</z> 
     </Property> 
     <Property Name="a1.2.1" Value="a"> 
      <x>x1.2.1</x> 
      <y>y1.2.1</y> 
      <z>z1.2.1</z> 
     </Property> 
     <Property Name="a1.2.2" Value="a"> 
      <x>x1.2.1</x> 
      <y>y1.2.1</y> 
      <z>z1.2.1</z> 
     </Property> 
     <Property Name="b1" Value="b"/> 
    </object> 
</root> 

Antwort

1

Re bearbeitete Frage - versuchen Sie es auf diese Weise:

XSLT 1,0

<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="Property"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()[not(self::Property)]"/> 
    </xsl:copy> 
    <xsl:apply-templates select="Property" /> 
</xsl:template> 

</xsl:stylesheet> 
2

Wenn Sie mit dem XSLT identity template beginnen, alles, was Sie brauchen, ist nur ein weiterer Vorlage, die Property entspricht, die das Element und die Attribute kopiert, aber die untergeordneten Elemente nach dem Element und nicht innerhalb des Elements ausgibt.

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

dieses XSLT Versuchen

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes" /> 
    <xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
    </xsl:template> 

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

Bitte beachte, dass ich Property Elemente gehe davon nur andere Property Elemente als Kinder hier enthalten.

+0

Vielen Dank für Ihre Hilfe. Ich hatte das Beispiel vereinfacht (ich habe meine Frage bearbeitet). Die zu kopierenden Knoten enthalten auch andere untergeordnete Knoten als die Eigenschaften, die mitkopiert werden müssen. Mit Ihrem XSLT verlieren die Eigenschaftsknoten ihren Inhalt. – Philippe