Замените HTML-кавычки обычным текстом в XSLT

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