Làm thế nào để bạn tách một chuỗi dựa trên một số dấu phân cách?Xslt có hàm split() không?
Cho một xâu Topic1,Topic2,Topic3
, tôi muốn chia chuỗi dựa trên ,
để generate:
Topic1 Topic2 Topic3
Làm thế nào để bạn tách một chuỗi dựa trên một số dấu phân cách?Xslt có hàm split() không?
Cho một xâu Topic1,Topic2,Topic3
, tôi muốn chia chuỗi dựa trên ,
để generate:
Topic1 Topic2 Topic3
Trong XSLT 1.0, bạn phải xây dựng một mẫu đệ quy. stylesheet này:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text/text()" name="tokenize">
<xsl:param name="text" select="."/>
<xsl:param name="separator" select="','"/>
<xsl:choose>
<xsl:when test="not(contains($text, $separator))">
<item>
<xsl:value-of select="normalize-space($text)"/>
</item>
</xsl:when>
<xsl:otherwise>
<item>
<xsl:value-of select="normalize-space(substring-before($text, $separator))"/>
</item>
<xsl:call-template name="tokenize">
<xsl:with-param name="text" select="substring-after($text, $separator)"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Input:
<root>
<text>Item1, Item2, Item3</text>
</root>
Output:
<root>
<text>
<item>Item1</item>
<item>Item2</item>
<item>Item3</item>
</text>
</root>
Trong XSLT 2.0, bạn có chức năng tokenize()
lõi. Vì vậy, kiểu này:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text/text()" name="tokenize">
<xsl:param name="separator" select="','"/>
<xsl:for-each select="tokenize(.,$separator)">
<item>
<xsl:value-of select="normalize-space(.)"/>
</item>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Kết quả:
<root>
<text>
<item>Item1</item>
<item>Item2</item>
<item>Item3</item>
</text>
</root>
Không có split
chức năng, nhưng bạn có thể sử dụng một mẫu đệ quy với substring-before
và substring-after
viết riêng của bạn.
Xem bài viết this để biết chi tiết.
Cảm ơn bạn user357812. Tôi sử dụng mẫu tốt đẹp của bạn với rất ít tùy biến để làm cho nó chung chung:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- Main template -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" mode="tokenize-children" />
</xsl:copy>
</xsl:template>
<!-- Split child nodes -->
<xsl:template match="*" mode="tokenize-children">
<xsl:copy>
<xsl:apply-templates select="@*" />
<xsl:apply-templates select="*" mode="tokenize" />
</xsl:copy>
</xsl:template>
<!-- Tokenize text node of child nodes -->
<xsl:template match="*/text()" name="tokenize" mode="tokenize">
<xsl:param name="text" select="."/>
<xsl:param name="separator" select="','"/>
<xsl:variable name="item" select="name(..)" />
<xsl:choose>
<xsl:when test="not(contains($text, $separator))">
<xsl:element name="{$item}">
<xsl:value-of select="normalize-space($text)"/>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:element name="{$item}">
<xsl:value-of select="normalize-space(substring-before($text, $separator))"/>
</xsl:element>
<xsl:call-template name="tokenize">
<xsl:with-param name="text" select="substring-after($text, $separator)"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Tùy thuộc vào những gì xử lý XSL bạn đang sử dụng, bạn có thể truy cập vào các chức năng mở rộng str:tokenize().
Vì vậy, để chia Topic1,Topic2,Topic3
trên ,
làm;
<xsl:copy-of select="str:tokenize('Topic1,Topic2,Topic3', ',')"/>
sẽ cho kết quả;
<token>Topic1</token>
<token>Topic2</token>
<token>Topic3</token>
XSLT 1.0
tôi cần một biến thể nhẹ so với câu trả lời khác đưa ra ở đây.
Input:
1, 2, 3
Ouput:
1, 2 và 3
Input:
Output
Nếu delimiter là không gian thay vì dấu phẩy, nó vẫn sẽ làm việc.
Input:
Ouput:
1, 2 và 3
Tôi vừa tạo một mẫu được sửa đổi một chút.
<xsl:template name="tokenizeString">
<xsl:param name="list"/>
<xsl:param name="delimiter"/>
<xsl:choose>
<xsl:when test="contains($list, $delimiter)">
<xsl:variable name="listLength" select="string-length($list)" />
<xsl:variable name="listLengthWithoutDelimiters" select="string-length(translate($list, $delimiter,''))" />
<xsl:variable name="noOfDelimiters" select="($listLength - $listLengthWithoutDelimiters)" />
<xsl:value-of select="substring-before($list,$delimiter)"/>
<xsl:if test="$noOfDelimiters > 1">, </xsl:if>
<xsl:if test="$noOfDelimiters = 1"> and </xsl:if>
<xsl:call-template name="tokenizeString">
<xsl:with-param name="list" select="substring-after($list,$delimiter)"/>
<xsl:with-param name="delimiter" select="$delimiter"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="$list = ''">
<xsl:text/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$list"/>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
Mẫu có thể được gọi như sau khi delimiter là dấu phẩy
<xsl:call-template name="tokenizeString">
<xsl:with-param name="list">1, 2, 3</xsl:with-param>
<xsl:with-param name="delimiter">
<xsl:value-of select="','" />
</xsl:with-param>
</xsl:call-template>
Mẫu có thể được gọi như sau khi delimiter là không gian
<xsl:call-template name="tokenizeString">
<xsl:with-param name="list">1 2 3</xsl:with-param>
<xsl:with-param name="delimiter">
<xsl:value-of select="' '" />
</xsl:with-param>
</xsl:call-template>
có thể bản sao của [XSLT có một hàm Split() không?] (http://stackoverflow.com/questions/136500/does-xslt-have-a-split-function) –