2010-06-20 11 views
6

Ich möchte nur wissen, ob es möglich ist, reguläre Ausdrücke im match Attribut des Elements xsl:template zu verwenden. Zum Beispiel nehme ich die folgen XML-Dokument haben:Reguläre Ausdrücke in xsl: Vorlage Übereinstimmung Attribut

<greeting> 
    <aaa>Hello</aaa> 
    <bbb>Good</bbb> 
    <ccc>Excellent</ccc> 
    <dddline>Line</dddline> 
</greeting> 

Nun ist die XSLT das obige Dokument zu transformieren:

<xsl:stylesheet> 

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

    <xsl:template match="matches(node-name(*),'line')"> 
     <xsl:value-of select="."/> 
    </xsl:template> 

</xsl:stylesheet> 

Wenn ich versuche, die Syntax matches(node-name(*),'line$') im match Attribut des xsl:template zu verwenden Element, ruft es eine Fehlermeldung ab. Kann ich im Attribut match reguläre Ausdrücke verwenden?

Vielen Dank

+2

Das nächste Mal bitte die Box neben dem Textfeld nur lesen, wo es heißt: *“ Formatieren: Code um 4 Leerzeichen einrücken "*. Dann müssen Sie '<' usw. nicht verwenden ... –

+0

Gute Frage (+1). Sehen Sie meine Antwort, die zu dieser Zeit die einzige vollständig korrekte Lösung für Ihre zwei verwandten Fragen enthält. :) –

Antwort

14

Dies ist die korrekte XSLT 1.0 Weise von passenden (in XSLT 2.0 die Streichhölzer() Funktion mit einem realen RegEx als pattern Argument):

ein Element-Matching, dessen Namen 'line':

<xsl:template match="*[contains(name(), 'line')]"> 
    <!-- Whatever processing is necessary --> 
</xsl:template> 

einen Elementnamen, deren Enden in passender 'line':

@Tomalak stellte eine weitere XSLT 1.0-Methode zum Suchen von Namen bereit, die mit einer gegebenen Zeichenfolge enden. Seine Lösung verwendet einen speziellen Charakter, der garantiert nie in irgendeinem Namen vorhanden ist. Meine Lösung kann angewendet werden, um zu ermitteln, ob eine Zeichenfolge (nicht nur ein Name eines Elements) mit einer anderen angegebenen Zeichenfolge endet.

In XSLT 2.x:

Verwendung: matches(name(), '.*line$') Namen übereinstimmen, die "line"

Diese Transformation mit der Zeichenfolge enden:

wenn auf Theis XML Dokument angewendet:

<greeting> 
    <aaa>Hello</aaa> 
    <bblineb>Good</bblineb> 
    <ccc>Excellent</ccc> 
    <dddline>Line</dddline> 
</greeting> 

Kopien an den Ausgang nur das Element, Name endet mit der Zeichenfolge, deren "line":

<dddline>Line</dddline> 

Während diese Umwandlung (verwendet matches(name(), '.*line')):

<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:template match="*[matches(name(), '.*line')]"> 
    <xsl:copy-of select="."/> 
</xsl:template> 

<xsl:template match="*[not(matches(name(), '.*line'))]"> 
    <xsl:apply-templates select="node()[not(self::text())]"/> 
</xsl:template> 
</xsl:stylesheet> 

Kopien an den Ausgang alle Elemente, deren Namen die Zeichenfolge enthalten "line":

<bblineb>Good</bblineb> 
<dddline>Line</dddline> 
+0

Vor allem, vielen Dank von Ihrer Mühe, es war das erste Mal, dass ich einen Zweifel in diesem Forum posten, ich bin wirklich eine Überraschung, dass Sie schnell reagierten. Ich vermisse die Version der Xslt, die ich vorgeben zu arbeiten, wird es be 2.0 und ja, ich möchte die Zeichenkette 'line' an der von einer Zeichenkette finden. Einmal mehr tnaks sehr von Ihrer Unterstützung – tt0686

+0

@pedromarquescosta: Gern geschehen. Ich habe meine Antwort mit der angeforderten XSLT 2.0-Lösung aktualisiert, die RegEx verwendet. –

5

In XSLT 1.0 (und 2.0, auch), für Ihr Beispiel (es ist nicht ein regulärer Ausdruck, obwohl):

<xsl:template match="*[contains(name(), 'line')]"> 
    <xsl:value-of select="."/> 
</xsl:template> 

und ein End-of-string Match zu erreichen :

<xsl:template match="*[contains(concat(name(), '&#xA;'), 'line&#xA;')]"> 
    <xsl:value-of select="."/> 
</xsl:template> 

in XSLT 2.0 können Sie natürlich die matches() Funktion anstelle von verwenden können.

+0

@Dimitre: Wie du gesagt hast, kann LF nicht Teil von 'name()' sein. Wenn Sie also XPath 2.0 (und Regex) nicht verwenden können, ist dies eine Möglichkeit, einen Namen zu finden, der an keiner Stelle die Zeichenfolge "line" enthält. Das OP scheint das zu wollen, weil er die Regex "line $" erwähnt, und er gab nicht die XSLT-Version an, die er benutzt. Ich hätte Platz oder irgendein anderes Zeichen verwenden können, das in Namen illegal ist. Es ist also überhaupt nicht sinnlos oder falsch. ;-) – Tomalak

+0

OK, ich sehe jetzt. Für Namen funktioniert das. –