2016-07-20 10 views
0

Ich versuche, eine gegebene XML mit xslt zu transformieren. Der Vorbehalt ist, dass ich einen Elternknoten löschen müsste, wenn ein bestimmter Kindknoten nicht vorhanden ist. Ich habe ein Template Matching gemacht, aber ich stecke fest. Jede Hilfe wäre willkommen.Entfernen Sie den übergeordneten Knoten, wenn der untergeordnete Knoten leer ist.

Der Eingang xml:

<?xml version="1.0" encoding="UTF-8"?> 
<main> 
    <item> 
     <value> 
      <item> 
       <value>ABC</value> 
       <key>test1</key> 
      </item> 
      <item> 
       <value>XYZ</value> 
       <key>test2</key> 
      </item> 
       <item> 
       <value></value> 
       <key>test3</key> 
      </item> 
     </value> 
    </item> 
    <item> 
     <value /> 
     <key>test4</key> 
    </item> 
    <item> 
     <value>PQR</value> 
     <key>test5</key> 
    </item> 
</main> 

Erwartete Ausgabe:

<?xml version="1.0" encoding="UTF-8"?> 
<main> 
    <item> 
     <value> 
      <item> 
       <value>ABC</value> 
       <key>test1</key> 
      </item> 
      <item> 
       <value>XYZ</value> 
       <key>test2</key> 
      </item> 
     </value> 
    </item> 
    <item> 
     <value>PQR</value> 
     <key>test5</key> 
    </item> 
</main> 

Das Problem ist, wenn ich Vorlage passende z.B.

<xsl:template match="item[not(value)]"/> wie in deleting the parent node if child node is not present in xml using xslt erwähnt, dann entfernt es vollständig alles wie Haupt/Element/Wert ist auch leer.

Was ich brauche, ist zu entfernen, wenn Element leer ist, aber nur tun, wenn Element kein Kindelement hat.

+0

Wenn der Wert für key test1 und test2 leer ist, sollte das Element item der obersten Ebene ebenfalls von der Ausgabe ausgeschlossen werden. – Ady211

Antwort

1

Sie sollten zunächst mit der XSLT-Identity-Vorlage

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

Dann starten Sie alles, was Sie brauchen, ist eine Vorlage, die item Element entspricht, in der alle Nachkomme Blatt value Elemente sind leer.

Also, die Vorlage entspricht, aber es gibt es nicht aus.

dieses XSLT Versuchen

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="xml" indent="yes" /> 

    <xsl:template match="item[not(descendant::value[not(*)][normalize-space()])]" /> 

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

Das funktioniert wie ein Zauber. Wie unterscheidet dieses xslt zwischen Haupt/Artikel/Wert (der leer ist und Kindknoten hat) gegen Artikel/Wert? Tut das nicht (*) den Trick? – Ady211

+0

Ja. Doing 'not (*)' prüft auf fehlende Unterelemente, so dass nur die "Blatt" -Elemente übereinstimmen. –

0

Ich denke, dass Sie das Element davon entfernen möchten, hat überhaupt keine Kinder (ob diese Kinder Elemente oder Textknoten sind). Experimentieren Sie mit dieser Vorlage:

<xsl:template match="item"> 
 
    <xsl:if test="exists(value/node())"> 
 
     <xsl:copy> 
 
      <xsl:copy-of select="@*"/> 
 
      <xsl:apply-templates/> 
 
     </xsl:copy> 
 
    </xsl:if> 
 
</xsl:template>

+0

Ich habe versucht, es funktioniert nicht und gibt xslt Kompilierungsfehler. Fehler: XSLTProcessor :: transformToXml(): xmlXPathCompiledEval: 1 auf dem Stapel verbliebene Objekte. – Ady211

+0

@ Ady211 Sind Sie sicher, dass Sie XSLT 2.0 verwenden, wie das Tag auf Ihrer Frage anzeigt? –

+0

Ich benutze xslt 1.0. – Ady211

0

Wenn ich das richtig gelesen, wollen Sie tun:

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="item[not(value[node()])]"/> 

</xsl:stylesheet> 

Dies wird jede item zu entfernen, die kein hat value Kind mit etwas Inhalt.

Verwandte Themen