Как заменить символ на рисунок (эмодзи) в XSLT / FO? - PullRequest
1 голос
/ 06 декабря 2011

Я видел похожие, но не совсем такие вопросы, как это, но вот что я пытаюсь сделать. У меня есть XML из моего SMS, и из него создайте журнал в формате PDF. Работает отлично. Попытка добавить этот новый элемент, и я получил функцию «заменить» в XSLT, работающую для замены символов, но я хочу вместо этого, вставить во внешнюю графику, используя переменную. Если я вставлю содержимое моей переменной XSLT непосредственно в документ FO, он создаст PDF без проблем, но я не перенесу свой тег и содержимое в файл FO. Я предполагаю, что мне не хватает чего-то простого.

Фрагмент XML:

<?xml version="1.0" encoding="UTF-8"?>
<SMSExport>
    <SMSMessage>
        <Kind>Sent</Kind>
        <DateTime>2011-11-08 12:14:23 -0800</DateTime>
        <Name>Sendee's name</Name>
        <Number>+15553009008</Number>
        <Message>Yay!!!  - </Message>
    </SMSMessage>
</SMSExport>

Фрагмент XML:

<xsl:if test="not(following-sibling::Message/@File)">
    <!-- Needs rework!!!  "Graphic not taking -->
    <xsl:variable name="emoji">
        <fo:external-graphic src="emoji/emoji-E057.png"
            content-height=".15in"/>
    </xsl:variable>
        <!-- Repeat added, to show a string replace works -->
    <xsl:value-of select="replace(following-sibling::Message, '', ';-)')"/>
        <fo:block/>
    <xsl:value-of select="replace(following-sibling::Message, '',$emoji)"/>
</xsl:if>

Получает полученный фрагмент блока FO:

<fo:block start-indent=".35in" end-indent=".25in" keep-with-next="always">
    Yay!!! ;-) - ;-);-);-)
        <fo:block/>
    Yay!!!  -
</fo:block>

Заранее спасибо!

ДОПОЛНЕНИЕ: (используя ответ LarsH, вот как я справился с рекурсией. Надеюсь, это может помочь кому-то еще.

Чтобы рекурсивно работать со строкой, я продолжал вставлять в блок выше, с новым регулярным выражением. Это помещало отдельные экземпляры анализа, и поэтому я продолжал повторять строку, заменяя каждый новый элемент. То есть с тремя блоками ищем три элемента (X, Y, Z):

This is the result of (x.gif)YZ.
This is the result of X(y.gif)Z.
This is the result of XY(z.gif).

Вместо того, что я хотел, что было:

This is the result of (x.gif)(y.gif)(z.gif).

Для других, чтобы справиться с этим, просто замените несоответствие

<xsl:copy-of select="."/>
Строка

с вложением следующего блока анализа (в этом примере я также подставил символ эмодзи с его шестнадцатеричным значением, чтобы избежать пустых полей). Я сделал это только для двух предметов / уровней, но вы бы просто продолжили вложение, и оно прекрасно работает:

<xsl:analyze-string select="following-sibling::Message" regex="&#xE057;">
    <xsl:matching-substring>
        <xsl:copy-of select="$E057"/>
    </xsl:matching-substring>
    <xsl:non-matching-substring>
        <xsl:analyze-string select="." regex="&#xE120">
            <xsl:matching-substring>
                <xsl:copy-of select="$E120"/>
            </xsl:matching-substring>
            <xsl:non-matching-substring>
                <xsl:copy-of select="."/>
            </xsl:non-matching-substring>
        </xsl:analyze-string>
     </xsl:non-matching-substring>
</xsl:analyze-string>

Ответы [ 2 ]

3 голосов
/ 06 декабря 2011

Функция replace() заменяет вхождения шаблона строкой. Строковое значение $emoji является объединением его текстовых узлов, а именно пустой строки. Другими словами, replace() не может делать то, что вам нужно.

Вопрос сводится к тому, как заменить символ (или шаблон) в строке фрагментом XML?

Хорошим решением является использование xsl:analyze-string для замены вхождений вашего шаблона '' на полностью структурированное содержимое $emoji:

<xsl:analyze-string select="following-sibling::Message" regex="">
  <xsl:matching-substring>
    <xsl:copy-of select="$emoji" />
  </xsl:matching-substring>
  <xsl:non-matching-substring>
    <xsl:value-of select="."/>
  </xsl:non-matching-substring>
</xsl:analyze-string>

вместо использования <xsl:value-of>, который может выводить только текст.

0 голосов
/ 20 июня 2013

Если вы используете XSLT 2.0, карты символов предоставляют более простой способ делать то, что вы хотите.Соответствующий раздел спецификации XSLT 2.0 содержит пример, включающий предоставление элементов img HTML для определенных символов.

...