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

发布于 2024-09-29 22:09:57 字数 840 浏览 9 评论 0原文

我有一个如下所示的 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 代码作为标签,但没有成功,所以我真的很困惑我做错了什么。

任何帮助表示赞赏, 谢谢

I have an xml document that looks like this.

<?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>

I've managed to get everything how I want but for one last tweak I'd like to have the Comma Separated Values display as a unordered list.

I'm using this line of XSL to output the list,

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

I'm getting an error saying that the resulting XML isn't formatted properly. I've tried to replace the replacement section with other stuff and it's worked. I've also tried using the HTML ASCII codes for the tags with no luck so I'm really confused with what I'm doing wrong.

Any help appreciated,
Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

无畏 2024-10-06 22:09:57

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

<xsl:value-of select="translate(tag,',','</li><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/作为递归模板来完成之后,这很痛苦。)

XSLT is XML; the select expression is embedded inside an attribute value so it must apply another round of XML-escaping. Since a CDATA section can't live in an attribute value, that has to be applied manually:

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

However, applying disable-output-escaping to the output of translate is questionable: what if the text had < or & characters in it? You'd be turning text content into active markup, with validity and potential security problems.

Normally it would be better to add markup from XSLT itself. You can split a string in XSLT 2.0 using the tokenize function:

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

(If you're using XSLT 1.0 this has to be done as a recursive template using substring_before/after, which is a pain.)

帅的被狗咬 2024-10-06 22:09:57
<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>
<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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文