XSL:translate()用替换字符串中的html

时间:2010-10-29 10:15:04

标签: xml xslt csv translate

我有一个看起来像这样的xml文档。

<?xml version="1.0"?>
<services>
    <service sn="1" family="2 Week Wait">
    <service_name>2 Week Wait Dermatology</service_name>
    <speciality>2 Week Wait</speciality>
    <clinic_types>2 Week Wait Skin</clinic_types>
    <tag>Malignant neoplasm of skin , Pigmented skin lesion </tag>
</service>

我已经设法得到了我想要的一切但是最后一次调整我希望将逗号分隔值显示为无序列表。

我正在使用这行XSL输出列表

<ul>
     <li>
           <xsl:value-of select="translate(tag,',','<![CDATA[</li><li>]]>')" disable-output-escaping="yes" />
     </li>
<ul>

我收到一条错误消息,指出生成的XML格式不正确。我试图用其他东西替换替换部分并且它有效。我也尝试过使用HTML ASCII码代码而没有运气,所以我真的很困惑我做错了。

任何帮助表示赞赏, 感谢

2 个答案:

答案 0 :(得分:3)

XSLT是XML; select表达式嵌入在属性值中,因此它必须应用另一轮XML转义。由于CDATA部分不能存在于属性值中,因此必须手动应用:

<xsl:value-of select="translate(tag,',','&lt;/li>&lt;li>')" disable-output-escaping="yes" />

但是,将disable-output-escaping应用于translate的输出值得怀疑:如果文字中包含<&字符会怎样?您将文本内容转换为活动标记,具有有效性和潜在的安全性问题。

通常,从XSLT本身添加标记会更好。您可以使用tokenize函数在XSLT 2.0中拆分字符串:

<ul>
    <xsl:for-each select="tokenize(tag,',')">
        <li><xsl:value-of select="."/></li>
    </xsl:for-each>
</ul>

(如果您使用的是XSLT 1.0,则必须使用substring_before / after作为递归模板完成,这很痛苦。)

答案 1 :(得分:-1)

<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="tag">
        <ul>
                <xsl:for-each select="tokenize(.,',')">
                    <li><xsl:value-of select="."/></li>
                </xsl:for-each>
            </ul>
</xsl:template>

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

</xsl:stylesheet>