Pytanie Zastąp znaki specjalne w XSLT


Chcę usunąć znaki inne niż alfabetu z ciągu w XSLT. Na przykład

<Name>O'Niel</Name> = <Name>ONiel</Name>
<Name>St Peter</Name> = <Name>StPeter</Name>
<Name>A.David</Name> = <Name>ADavid</Name>

Czy możemy użyć Wyrażenia regularnego w XSLT, aby to zrobić? Który jest właściwy sposób wdrożenia tego?

EDYCJA: To musi zrobić na XSLT 1.0.


9
2018-02-22 21:17


pochodzenie


sprawdź moją odpowiedź, jak to zrobić bez RegExp, które nie są obsługiwane w XSLT / XPath 1.0 przy okazji. - Flack


Odpowiedzi:


W tym celu istnieje czysty sposób XSLT.

<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:variable name="vAllowedSymbols"
        select="'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'"/>
    <xsl:template match="node() | @*">
        <xsl:copy>
            <xsl:apply-templates select="node() | @*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="text()">
        <xsl:value-of select="
            translate(
                .,
                translate(., $vAllowedSymbols, ''),
                ''
                )
            "/>
    </xsl:template>
</xsl:stylesheet>

Wynik dla tej próbki:

<t>
    <Name>O'Niel</Name>
    <Name>St Peter</Name>
    <Name>A.David</Name>
</t>

Będzie:

<t>
    <Name>ONiel</Name>
    <Name>StPeter</Name>
    <Name>ADavid</Name>
</t>

19
2018-02-22 21:47



@Flack - To jest świetne. Moje rozwiązanie było użyteczne przy zamianie pojedynczych znaków na czarnej liście na inną sekwencję znaków, ale translate jest znacznie lepszym rozwiązaniem do zastosowania białej listy lub prostych zamienników jeden do jednego. - Wayne Burkett
@lwburk. Możesz użyć translate dla "czarnej listy" również. Byłoby jeszcze prostsze. Bez potrzeby rekursji, gdy nie potrzebujesz "zamiany łańcucha na inny ciąg". - Flack
Jak zastosować ten szablon dla węzła takiego jak ten / Aplikacja / Kontakt / Imię? - Amzath
@Amzath. Zasadniczo można użyć XPath Expr począwszy od translate za każdym razem, gdy bierzesz wartości ciągów węzłów i atrybutów. - Flack
@Flack - Tak, to jest część tego, co próbowałem powiedzieć, i właśnie dlatego usunąłem mój post. Potrzebujesz podejścia rekurencyjnego w XSLT 1.0 do wykonywania bardziej skomplikowanych zamienników, ale w tym przypadku była to kompletna przesada. - Wayne Burkett


Oto opcja 2.0:

EDYCJA: Przepraszam ... Wymóg 1.0 został dodany po tym, jak zacząłem od odpowiedzi.

XML

<?xml version="1.0" encoding="UTF-8"?>
<doc>
  <Name>O'Niel</Name>
  <Name>St Peter</Name>
  <Name>A.David</Name>
</doc>

XSL

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

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

  <xsl:template match="text()">
    <xsl:value-of select="replace(.,'[^a-zA-Z0-9]','')"/>
  </xsl:template>

</xsl:stylesheet>

wydajność

<?xml version="1.0" encoding="UTF-8"?>
<doc>
   <Name>ONiel</Name>
   <Name>StPeter</Name>
   <Name>ADavid</Name>
</doc>

9
2018-02-22 21:53





Właśnie utworzyłem funkcję opartą na kodzie w tym przykładzie ...

    <xsl:function name="lancet:stripSpecialChars">
    <xsl:param name="string" />
    <xsl:variable name="AllowedSymbols" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789()*%$#@!~&lt;&gt;,.?[]=- +   /\ '"/>
    <xsl:value-of select="
        translate(
            $string,
            translate($string, $AllowedSymbols, ''),
            ' ')
        "/>
</xsl:function> 

a przykład użycia będzie następujący:

<xsl:value-of select="lancet:stripSpecialChars($string)"/>

2
2018-06-08 09:15