2016-04-20 13 views
0

Ich verwende diese Vorlage für das Kopieren ohne Namensraum:Kopieren ohne Namensraum mit Kriterien in Xslt

<xsl:template match="*" mode="copy-no-namespaces"> 
    <xsl:element name="{local-name()}"> 
     <xsl:copy-of select="@*"/> 
     <xsl:apply-templates select="node()" mode="copy-no-namespaces"/> 
    </xsl:element> 
</xsl:template> 

<xsl:template match="comment()| processing-instruction()" mode="copy-no-namespaces"> 
    <xsl:copy/> 
</xsl:template> 

das funktioniert. Aber ich möchte, dass es ohne bestimmten Namespace und nicht mit allen Namespaces kopiert wird. Zum Beispiel möchte ich einige Namespaces wie http://test.com, http://test2.com ignorieren, sollte die Kopie nur diese Namespaces, nicht alle Namespace entfernen.

Beispiel:

<xs:schema xmlns:xxx="http://include.com" xmlns:xs="http://www.w3.org/2001/XMLSchema" 
xmlns:zzz="http:test.com" > 
    <zzz:element> 
    </zzz:element> 

    <xxx:complexType> 
    </xxx:complexType> 
</xs:schema> 

Hier zzz Namespace entfernt werden sollen, sondern bewahren xxx als zzznur Matches http://test.com, so wird der Ausgang seiner

<xs:schema xmlns:xxx="http://include.com" xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <element> 
    </element> 

    <xxx:complexType> 
    </xxx:complexType> 
</xs:schema> 

Wie kann ich das erreichen?

+0

Könnten wir ein Beispiel testen gegen: [MCVE] –

+0

@ michael.hor257k: Fertig. –

Antwort

2

Ich denke, Sie können zwischen dem Verschieben von Elementen in einen anderen (oder keinen) Namespace und Kopieren von Namespaces (d. H. Namespacedeklarationen) verwirren. Sie sollten nur die zzz: Präfix Elemente zu No-Namespace verschieben müssen - und nicht, wenn die Ausgabe eine mittlerweile redundante Namespace-Deklaration enthält:

XSLT 1,0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:ns1="http:test.com" 
exclude-result-prefixes="ns1"> 
<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="ns1:*"> 
    <xsl:element name="{local-name()}"> 
     <xsl:copy-of select="@*"/> 
     <xsl:apply-templates/> 
    </xsl:element> 
</xsl:template> 

</xsl:stylesheet> 

P. S. Wenn Sie möchten, können Sie das gleiche tun, ohne Präfix erklärt:

<xsl:template match="*[namespace-uri()='http:test.com']"> 
    <xsl:element name="{local-name()}"> 
     <xsl:copy-of select="@*"/> 
     <xsl:apply-templates/> 
    </xsl:element> 
</xsl:template> 
+0

Was Sie gesagt haben, ist korrekt, aber wie kann ich die 'xsl: template match =" zzz: * 'so aussehen wie' match = "namespace: "? Weil Namespacepräfix kann sein jeder, also muss ich nur basierend auf der URL übereinstimmen.Jeglicher Hinweis? –

+0

Der Namespace, der dem Präfix zugeordnet ist, ist im Stylesheet definiert, das Präfix kann alles sein, was Sie wollen.Wenn das XML ändert, um ein anderes Präfix für das gleiche zu verwenden Namespace, es wird immer noch funktionieren. - Ich habe die Antwort bearbeitet, um das klarer zu machen - und einen alternativen Ansatz hinzugefügt, der den Namespace direkt verwendet, ohne ihn an ein Präfix zu binden. –

+1

@ Ant's Wie gesagt, Sie sollten sich nicht darum kümmern Das Steuern des Kopierens von Namespaces ist in XSLT 1.0 schwierig, und was mit einem Prozessor funktioniert, funktioniert möglicherweise nicht mit einem anderen. Warum ist das für Sie wichtig? –

0

eine Vorlage mit höherer Priorität Verwenden Sie Elemente in bestimmten Namensraum zu halten:

<xsl:template match="*" 
       mode="copy-no-namespaces"> 
    <xsl:element name="{local-name()}"> 
    <xsl:apply-templates select="node() | @*" mode="copy-no-namespaces"/> 
    </xsl:element> 
</xsl:template> 

<xsl:template match="xxx:*" xmlns:xxx="http://include.com" 
       mode="copy-no-namespaces"> 
    <xsl:element name="{name()}" namespace="{namespace-uri()}"> 
    <xsl:apply-templates select="node() | @*" mode="copy-no-namespaces"/> 
    </xsl:element> 
</xsl:template> 

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

Die erste Vorlage Streifen Namensräume aus Elementen, behält der zweite Namensraum http://include.com in Elemente und die letzte alles andere Kopien.

Die zweite Vorlage könnte xsl:copy anstelle von xsl:element verwenden, aber das würde alle Namespaces im Geltungsbereich kopieren, und Sie würden mit redundanten Namespacedeklarationen enden.

+0

danke. Können wir es nicht anders machen als erwarten 'http: // test.com' Namespace, alles andere? anstatt hart codiert, um 'xxx: *' zu entsprechen? –