2011-12-05 3 views
1

Я видел похожие, но не совсем вопросы, как это, но вот что я пытаюсь сделать. У меня есть XML из моего SMS, и из него создайте журнал PDF. Прекрасно работает. Попробовал добавить этот новый элемент, и я получил функцию «replace» в XSLT, чтобы заменить символы, но вместо этого я хочу использовать внешнюю графику с использованием переменной. Если я вставляю содержимое своей переменной XSLT непосредственно в документ FO, он создает PDF без проблем, но я не получаю свой тег и содержимое в файл FO. Я предполагаю, что я пропустил что-то простое.Как заменить символ графикой (emoji) в XSLT/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> 

ответ

3

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

Большое спасибо. Это сработало отлично.Единственная проблема заключалась в том, чтобы выяснить, как это сделать на строке рекурсивно. Я не могу подходить к нему как к комментарию, так что он поместит его, как еще один ответ. – LOlliffe

+0

@LOlliffe: Вы имеете в виду необходимость замены разных символов в одной и той же строке разными поддеревьями? Я бы, вероятно, использовал select-when-test-иначе в ''. Но похоже, что вы уже нашли решение. :-) – LarsH

+0

@LOlliffe: чтобы прояснить мой предыдущий комментарий: я имел в виду поместить альтернативных символов в атрибут regex '', например. 'regex =" [& # xE057; & # xE120;] "', а затем используя '', как уже упоминалось. Преимущество этого метода заключается в том, что глубина рекурсии строго ограничена. Но ваш способ (встраивание другой xsl: аналитической строки внутри xsl: non-matching-substring) тоже работает. – LarsH

0

Если вы используете XSLT 2.0, карты символов обеспечивают более простой способ делать то, что вы хотите. relevant section of the XSLT 2.0 spec имеет пример, который включает в себя поставку элементов HTML img для определенных символов.