#html #xslt
#HTML #xslt
Вопрос:
Мы используем XSLT для перевода файла RIXML в XML. Наш RIXML содержит следующий текст:
<Title><![CDATA[Looking into the future: Reiterate amp;#8216;Buyamp;#8217;]]></Title>
8216 — это цитата слева, а 8217 — цитата справа.
Как бы мне заменить эти HTML-коды их обычным текстовым представлением или, проще говоря, просто одинарной кавычкой? Это XSLT версии 1.0.
Комментарии:
1. Непонятно, почему вы используете разделы CDATA. Эти ссылки на символы разрешены в XML. Кроме того, принятый ответ не будет работать с вашим исходным образцом как есть.
2. Мы получаем этот XML из стороннего источника. Насколько я понимаю, это также было неверно.
Ответ №1:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:variable name="vQ2">""</xsl:variable>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()">
<xsl:value-of select=
"translate(.,'amp;#8216;amp;#8217;',$vQ2)"/>
</xsl:template>
</xsl:stylesheet>
Комментарии:
1. В моей конкретной реализации мне нужно было экранировать амперсанды таким образом: <xsl:value-of select=»перевести(узел, ‘amp;amp;#8216;amp;amp; # 8217;’, $ vQ2)»/>
2. @frinkenstein789: это странно. Если вам пришлось дважды экранировать, вы делаете что-то необычное, о чем вы нам не рассказали. Однако ни предоставленное решение, ни ваша версия с двойным экранированием не должны работать, если входные данные в том виде, в каком они были предоставлены, с разделом CDATA, потому что amp;# 8216; в разделе CDATA представляет собой 7 символов, а не один.
3. @Michael-Kay: Да, в этом случае следует использовать
replace()
функцию (XPath 2.0) или рекурсивный именованный шаблон. Я думал, что OP только случайно использовал CDATA.
Ответ №2:
Я наткнулся на эту функцию, которая у меня хорошо работала. Я вызываю это, чтобы заменить все символы, которые мне нужны для:
<xsl:template name="string-replace-all">
<xsl:param name="text" />
<xsl:param name="replace" />
<xsl:param name="by" />
<xsl:choose>
<xsl:when test="contains($text, $replace)">
<xsl:value-of select="substring-before($text,$replace)" />
<xsl:value-of select="$by" />
<xsl:call-template name="string-replace-all">
<xsl:with-param name="text"
select="substring-after($text,$replace)" />
<xsl:with-param name="replace" select="$replace" />
<xsl:with-param name="by" select="$by" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>