2

我有一个看起来像这样的 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 代码作为标签,但没有成功,所以我真的对自己做错了什么感到困惑。

任何帮助表示赞赏,谢谢

4

2 回答 2

2

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,这很痛苦。)

于 2010-10-29T10:41:02.613 回答
-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>
于 2021-07-24T16:10:49.793 回答