XSLT: заменить одинарные кавычки на \ ' - PullRequest
3 голосов
/ 10 октября 2011

Я использую XSLT для преобразования XML в html / php файл.В этом XSLT я заменяю некоторые теги на php-код, и теперь мне нужно передать значения атрибутов в этот php-код.Моя проблема сейчас в том, что мне нужно экранировать одинарные кавычки с обратной косой чертой, чтобы это работало.Возможно ли это с XSLT.

Пример:

<xsl:template match="foo">
    <xsl:processing-instruction name="php">$this->doSomething('<xsl:value-of select="./@bar" />');</xsl:processing-instruction>
</xsl:template>

Если бы у меня теперь был шаблон:

<foo bar="test'xyz"/>

Это сгенерировало бы:

<?php $this->doSomething('test'xyz');?>

Теперь я хочу добиться следующего:

<?php $this->doSomething('test\'xyz');?>

Поэтому я хочу заменить все одинарные кавычки на \ '

Ответы [ 5 ]

6 голосов
/ 10 октября 2011

Используйте рекурсивный шаблон для поиска / замены:

<xsl:template name="replace-string">
    <xsl:param name="text"/>
    <xsl:param name="replace"/>
    <xsl:param name="with"/>
    <xsl:choose>
      <xsl:when test="contains($text,$replace)">
        <xsl:value-of select="substring-before($text,$replace)"/>
        <xsl:value-of select="$with"/>
        <xsl:call-template name="replace-string">
          <xsl:with-param name="text"
                          select="substring-after($text,$replace)"/>
          <xsl:with-param name="replace" select="$replace"/>
          <xsl:with-param name="with" select="$with"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$text"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

Применимо к вашему примеру:

   <xsl:template match="foo">
    <xsl:processing-instruction name="php">
        <xsl:text>$this->doSomething('</xsl:text>
        <xsl:call-template name="replace-string">
            <xsl:with-param name="text" select="./@bar"/>
            <xsl:with-param name="replace" select='"&apos;"' />
            <xsl:with-param name="with" select='"\&apos;"'/>
        </xsl:call-template>
        <xsl:text>');</xsl:text>
    </xsl:processing-instruction>
</xsl:template>

Примечание:

  1. Использование <xsl:text> для явного определения текста, предназначенного для вывода, и не нужно беспокоиться о пробелах между этим текстом и вызовами шаблона.
  2. Использование одинарных кавычек для включения оператора выбора для параметров replace и с для использования двойных кавычек для обозначения текстового оператора, который содержитодиночная кавычка
  3. Использование ссылки на сущность &apos; для одинарной кавычки (он же апостроф)
2 голосов
/ 10 октября 2011

Для решения XSLT 1.0 либо напишите собственное рекурсивное решение, либо вы можете использовать FXSL шаблон str-map:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:testmap="testmap" xmlns:f="http://fxsl.sf.net/"
exclude-result-prefixes="xsl f testmap"
>
   <xsl:import href="str-dvc-map.xsl"/>

   <testmap:testmap/>

   <xsl:variable name="vTarget">'</xsl:variable>
   <xsl:variable name="vReplacement">\</xsl:variable>

   <xsl:output omit-xml-declaration="yes" indent="yes"/>

   <xsl:template match="/">
     <xsl:variable name="vTestMap" select="document('')/*/testmap:*[1]"/>
     <xsl:call-template name="str-map">
       <xsl:with-param name="pFun" select="$vTestMap"/>
       <xsl:with-param name="pStr" select="string(/*/@bar)"/>
     </xsl:call-template>
   </xsl:template>

    <xsl:template name="escapeApos" mode="f:FXSL"
         match="*[namespace-uri() = 'testmap']">
      <xsl:param name="arg1"/>

      <xsl:if test="$arg1 = $vTarget">
       <xsl:value-of select="$vReplacement"/>
      </xsl:if>
      <xsl:value-of select="$arg1"/>
    </xsl:template>
</xsl:stylesheet>

При применении к предоставленному документу XML :

<foo bar="test'xyz"/>

желаемый, правильный результат получается :

test\'xyz
2 голосов
/ 10 октября 2011

Почему бы вам просто не использовать стандартную функцию замены XSLT 2.0?Или реализация замены XSLT 1.0 Функция замены строки xslt 1.0

1 голос
/ 26 мая 2018

Вот более простой, не элегантный, но быстрый способ замены одинарных кавычек:

<xsl:variable name="single_quote"><xsl:text>'</xsl:text></xsl:variable>
<xsl:variable name="temp_filename" select="replace($temp_filename,$single_quote,'')"/>

1) Определите переменную, которая содержит только апостроф. xsl: текст необходим, чтобы xsl рассматривал 'как простой символ

2) Используйте функцию замены, используя эту переменную в качестве строки для сопоставления. В этом примере я просто удаляю его.

0 голосов
/ 10 октября 2011

Просто используйте:

$string = str_replace( "'", "\\'", $string );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...