2016-06-03 45 views
1

übereinstimmen Ich habe eine Inkscape-Svg-Datei.wie Knoten und Kind-Knoten (gleicher Name) in xsl: Vorlage

vereinfachte Version:

<svg> 
    <g inkscape:label="layerA"> 
     <g inkscape:label="layerB"/> 
    </g> 
    <g inkscape:label="layerC"> 
     <g inkscape:label="layerD"/> 
    </g> 
</svg> 

Ich möchte ein um die Schichten extrahieren (und B), und D.

Das für die Schicht A arbeitet, die direkt unter dem Wurzelelement ist.

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet 
    version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:svg="http://www.w3.org/2000/svg" 
    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" 
> 

<!-- Auto intend --> 
<xsl:output indent="yes"/> 

<!-- Copy every other node, element, attribute --> 
<xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
</xsl:template> 

<!-- Do not copy any other group --> 
<xsl:template match="svg:g"/> 

<!-- Copy all matching groups --> 
<xsl:template match="svg:g[@inkscape:label='layerA']|svg:g[@inkscape:label='layerD']"> 
    <xsl:copy-of select="."/> 
</xsl:template> 

Aber es Schicht D. meine Frage nicht kopieren

So ist: Wie kann ich direkt unter root nicht nur die Knoten entsprechen, aber unter einem anderen "g" Elemente.

+0

Ihre "vereinfachte" Version der Eingabe ist kein wohlgeformtes XML und stimmt nicht mit Ihrem Stylesheet überein - was die Reproduktion Ihres Problems erschwert. –

Antwort

2

Statt:

<!-- Do not copy any other group --> 
<xsl:template match="svg:g"/> 

tun:

<xsl:template match="svg:g"> 
    <xsl:apply-templates select="svg:g"/> 
</xsl:template> 

Ansonsten Ihre nächste Vorlage:

<!-- Copy all matching groups --> 
<xsl:template match="svg:g[@inkscape:label='layerA']|svg:g[@inkscape:label='layerD']"> 
    <xsl:copy-of select="."/> 
</xsl:template> 

nie

+0

Danke. Es funktioniert. Aber ich habe keine Ahnung warum. :) Sind meine Kommentare sogar richtig? Bedeutet die zweite 'xsl: template' _" nicht kopieren "_, weil es keinen' xsl: copy' Befehl gibt? Wenn ja: Wie beeinflusst diese Vorlage die Lest-Vorlage? Sorry, ich bin komplett neu bei xsl. :) –

+0

Sie müssen das [XSLT-Verarbeitungsmodell] (https://www.w3.org/TR/xslt/#section-Processing-Model) verstehen, das rekursiv arbeitet. Wenn Sie eine Vorlage haben, die nichts tut, stoppt die Rekursion dort. So gelangt der Prozessor niemals zu Schicht D, weil er in Schicht C gestoppt wird. –

+0

P.S. Wir gehen hier davon aus, dass Sie die Vorlage * identity transform * (Ihre erste Vorlage) für einige andere Knoten benötigen, die in Ihrem Eingabebeispiel nicht gezeigt werden. Andernfalls könnte Ihre Struktur von * Regel/Ausnahme von der Regel/Ausnahme von der Ausnahme * vereinfacht werden, wie in der anderen Antwort gezeigt. –

0

Diese com Schicht D. angewendet werden plette Transformation:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:svg="http://www.w3.org/2000/svg" 
    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="/*"> 
    <xsl:copy> 
    <xsl:copy-of select=".//svg:g[@inkscape:label='layerA' or @inkscape:label='layerD']"/> 
    </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

wenn auf der mitgelieferten XML angewandt Dokument (mit zusätzlichen Namespace-Deklarationen, um es wohlgeformt):

<svg xmlns="http://www.w3.org/2000/svg" 
    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"> 
    <g inkscape:label="layerA"> 
     <g inkscape:label="layerB"/></g> 
    <g inkscape:label="layerC"> 
     <g inkscape:label="layerD"/></g> 
</svg> 

produziert (was ich denke, ist) das wollte , korrektes Ergebnis:

<svg xmlns="http://www.w3.org/2000/svg" 
    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"> 
    <g inkscape:label="layerA"> 
     <g inkscape:label="layerB"/> 
    </g> 
    <g inkscape:label="layerD"/> 
</svg> 
0

Nochmals vielen Dank für Ihre Antworten!

Ich möchte nur einen alternativen Weg zu meinem Ziel (ein Png-Export mit einer Teilmenge der Schichten innerhalb einer Svg) hinzufügen.

https://github.com/wader/inkmake

Die inkfile sieht wie folgt aus:

output.png input.svg -* +layerA +layerB +layerD 

Das erspart mir die Mühe von vielen neuen SVG-Dateien genarationg, bevor sie in png exportieren.

Aber danke nochmal.