Как удалить символы из xsl, где находится текст из инструкции по обработке - PullRequest
2 голосов
/ 25 января 2011

Эта проблема аналогична упомянутой здесь , как удалить XML с xslt , но немного отличается, поскольку мой текст исходит из инструкции по обработке.

У меня есть такая инструкция:

<?xm-mark data="&lt;p>Here is the text&lt;/p>" ?>

И я хотел бы вывести часть данных с незашифрованным &lt;.Моя попытка на данный момент такова:

<xsl:template match="processing-instruction('xm-mark')">
  <mymark>
  <xsl:value-of select="substring-before(substring-after(., 'data=&quot;'), '&quot;')"
  disable-output-escaping="yes" />
  </mymark>
</xsl:template>

Однако это возвращает мне текст &lt;p>.Если я удаляю disable-output-escaping = "yes", я получаю обратно &amplt; (двойное кодирование, как я и ожидал).Поскольку я не могу поместить значение в значение в шаблоне, есть идеи, как я могу удалить данные?

Ответы [ 2 ]

3 голосов
/ 25 января 2011

Это то, что вы получаете, когда уничтожаете разметку, конвертируя ее в текст .

Не забывайте никогда не "создавать" такие ужасные вещи.

Такжеобращение к DOE является признаком отчаяния, и вовсе не гарантирует работу вообще (DOE не является обязательной функцией, и некоторые основные процессоры XSLT 1.0, такие как тот, что используется FF, не работаютреализовать его).

Итак, какая другая альтернатива существует ?

Одним из возможных решений является написание функции расширения (такой стандартной функции нет в XSLT / XPathверсии 1.0 и 2.0), которая принимает строку, анализирует ее как XML и возвращает полученный XML-документ.Будет использоваться так:

  <xsl:copy-of select=
      "xx:parse(substring-before(substring-after(., 'data=&quot;'), '&quot;'))/*"/>
1 голос
/ 25 января 2011

Обработка инструкций не требует экранирования чего-либо, они анализируются аналогично комментариям, так как все, что находится между <? и ?>, обрабатывается как есть. Если вы можете, вам нужно изменить то, что генерирует эту инструкцию, чтобы сгенерировать это:

<?xm-mark data="<p>Here is the text</p>" ?>

Если вы не можете этого сделать, я бы даже не пытался использовать XSLT для его анализа.

РЕДАКТИРОВАТЬ: я, вероятно, должен уточнить, так как вы, вероятно, делаете вещи более сложными, чем вам нужно здесь: инструкция обработки не имеет атрибутов, и даже "и пробел в конце являются частью значения" 'узла инструкции обработки. Вы получили инструкцию обработки с именем xm-mark и значением data="<p>Here is the text</p>" здесь (включая пробел в конце, который здесь не отображается); data столько же часть значения как <p>..</p> part.

В вашем случае, вероятно, достаточно <?xm-mark <p>Here is the text</p>?>, тогда значение узла инструкции обработки равно <p>Here is the text</p>, и это все, что вас, вероятно, заинтересует.

РЕДАКТИРОВАТЬ: Ой ... ну, вы можете попробовать это:

  <xsl:template match="processing-instruction('xm-mark')">
    <xsl:element name="mymark">
      <xsl:call-template name="unescape">
        <xsl:with-param name="input" select="substring-before(substring-after(., 'data=&quot;'), '&quot;')" />
      </xsl:call-template>
    </xsl:element>
  </xsl:template>

  <xsl:template name="unescape">
    <xsl:param name="input" />
    <xsl:choose>
      <xsl:when test="contains($input, '&amp;lt;')">
        <xsl:call-template name="unescape">
          <xsl:with-param name="input" select="substring-before($input, '&amp;lt;')" />
        </xsl:call-template>
        <xsl:text>&lt;</xsl:text>
        <xsl:call-template name="unescape">
          <xsl:with-param name="input" select="substring-after($input, '&amp;lt;')" />
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$input" />
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

Примечание: поскольку & воспринимается как текст, а не как разметка, при обработке с помощью xslt вам необходимо использовать &amp; для ссылки на него. Следовательно, значение вашей инструкции обработки фактически представляется как &amp;lt;p&gt;etc.., если оно было выведено «как есть» в XML-документе. Приведенный выше xsl по крайней мере преобразует это в &lt;p&gt;etc.., но если вы хотите фактические теги p, используйте метод расширения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...