2013-07-04 9 views
6

Nie mogę znaleźć dokładnej odpowiedzi na to pytanie, więc mam nadzieję, że ktoś mi w tym pomoże.Substring po ostatnim znaku w xslt

Mam ciąg znaków i chcę uzyskać podciąg po ostatnim ".". Używam xslt 1.0.

Jak to zrobić? To jest mój kod.

<xsl:choose> 
    <xsl:otherwise> 
     <xsl:attribute name="class">method txt-align-left case-names</xsl:attribute>&#160; 
     <xsl:value-of select="./@name"/> // this prints a string eg: 'something1.something2.something3' 
    </xsl:otherwise> 
</xsl:choose> 

Po wklejeniu sugerowanego kodu pojawia się komunikat o błędzie. "Parsowanie arkusza stylów XSLT nie powiodło się."

Odpowiedz

14

nie mogę wymyślić sposób, aby to zrobić za pomocą jednego wyrazu w XSLT 1.0, ale można to zrobić za pomocą rekurencyjnego wzoru:

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

    <xsl:template match="/"> 
    <n> 
     <xsl:call-template name="GetLastSegment"> 
     <xsl:with-param name="value" select="'something1.something2.something3'" /> 
     <xsl:with-param name="separator" select="'.'" /> 
     </xsl:call-template> 
    </n> 
    </xsl:template> 

    <xsl:template name="GetLastSegment"> 
    <xsl:param name="value" /> 
    <xsl:param name="separator" select="'.'" /> 

    <xsl:choose> 
     <xsl:when test="contains($value, $separator)"> 
     <xsl:call-template name="GetLastSegment"> 
      <xsl:with-param name="value" select="substring-after($value, $separator)" /> 
      <xsl:with-param name="separator" select="$separator" /> 
     </xsl:call-template> 
     </xsl:when> 
     <xsl:otherwise> 
     <xsl:value-of select="$value" /> 
     </xsl:otherwise> 
    </xsl:choose> 
    </xsl:template> 
</xsl:stylesheet> 

Wynik:

<n>something3</n> 
+0

Można by to zrobić: ' 'Jeśli możesz ' t zmusić to do pracy, czy możesz edytować swoje pytanie, aby uwzględnić wszystkie istotne części twojego XSLT? – JLRishe

0

I rozwiązany to

<xsl:call-template name="GetLastSegment"> 
<xsl:with-param name="value" select="./@name" /> 
</xsl:call-template> 

nie potrzebujemy

<xsl:with-param name="separator" value="'.'" /> 

w wywołaniu szablonu

3

zrobiłem to samo zachowanie z xsl: function - wykorzystywany jest wtedy nieco prostsze:

<xsl:function name="ns:substring-after-last" as="xs:string" xmlns:ns="yourNamespace"> 
    <xsl:param name="value" as="xs:string?"/> 
    <xsl:param name="separator" as="xs:string"/>   
    <xsl:choose> 
     <xsl:when test="contains($value, $separator)"> 
      <xsl:value-of select="ns:substring-after-last(substring-after($value, $separator), $separator)" /> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:value-of select="$value" /> 
     </xsl:otherwise> 
    </xsl:choose> 
</xsl:function> 

I można nazwać to bezpośrednio na wartość od :

<xsl:value-of select="ns:substring-after-last(.,'=')" xmlns:ns="yourNamespace"/> 
+0

Skąd pochodzi przestrzeń nazw? 'dp: substring-after-last (substring-after ($ value, $ separator), $ separator)' ' – Hayra

+0

Dzięki Hayra ... W przedrostku przestrzeni nazw rzeczywiście wystąpił błąd kopiowania/wklejania. Właśnie zaktualizowałem kod: – FiveO

+0

który namespace to ns? – zypro

1

Tutaj jest rozwiązanie wykorzystujące EXSLT str:tokenize:

<xsl:if test="substring($string, string-length($string)) != '.'"><xsl:value-of select="str:tokenize($string, '.')[last()]" /></xsl:if> 

(the if jest tutaj, bo jeśli ciąg kończy się z separatorem, tokenize nie zwróci pusty ciąg)