2016-12-19 7 views
0

У меня есть XML, который в одном узле имеет кучу текста с несколькими абзацами. Мне нужно заменить \ n на </p><p>, в текстовом разделе все будут иметь <p> в начале и </p> в конце определения XSLT.XSLT заменить n на</p><p>

Я попытался это, но он дает мне ошибку в Saxon: Переменная find_all не была объявлена ​​(или декларация не в объеме)

<xsl:template match="/csv/row/col[17]"> 
    <xsl:param name="find_all"> 
     <xsl:value-of select="."/> 
    </xsl:param> 
    <xsl:param name="find_return"> 
     <xsl:text>(.*)\n(.*)</xsl:text> 
    </xsl:param> 
    <xsl:param name="replace_return"> 
     <xsl:text>$1&lt;/p&gt;&lt;p&gt;$2</xsl:text> 
    </xsl:param> 
</xsl:template> 

И потом это:

<col name="Model descr."> 
    <content> 
     <xsl:text>&lt;p&gt;</xsl:text> 
    </content> 
    <content> 
     <xsl:value-of select="replace($find_all, $find_return, $replace_return)"/> 
    </content> 
    <content> 
     <xsl:text>&lt;/p&gt;</xsl:text> 
    </content> 
</col> 

Что здесь не так?

Благодаря

Jan

ответ

1

Вы принимаете неправильный подход здесь. Для начала, из фрагментов, которые вы нам показали, у вас есть шаблон с параметрами, но эти параметры являются локальными по охвату этого шаблона. Если вы пытаетесь использовать эти параметры вне шаблона, они не будут доступны.

Кроме того, функция replace работает со строками, и вы не можете использовать ее для создания новых элементов, таких как <p>. То, что вы создадите в своем выводе, - это значение, оставшееся от &lt;p&gt;.

Другой подход к использованию - использовать функцию tokenize, разделить текст на основе разрыва строки и перебрать каждый элемент, обернув его в новый тег <p>.

Попробуйте XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 
    <xsl:output method="xml" indent="yes" /> 

    <xsl:template match="text()" priority="2"> 
     <xsl:for-each select="tokenize(., '\n')[normalize-space()]"> 
      <p> 
       <xsl:value-of select="." /> 
      </p>    
     </xsl:for-each> 
    </xsl:template> 

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

Вам также может понадобиться '', чтобы избежать двух уровней 'p' тегов, если есть существуют отмеченные абзацы. –

+0

Я не уверен, что это сработает для меня. То, что я работаю, - это система, которая получает XML, отправляет ее процессору, который создает HMTL, а из HTML выводит PDF-файл.Каждый узел в моем XML предназначен для переменной в JavsScript, который сочетается с HTML-шаблоном, который становится PDF. Итак, в шаблоне HTML у нас уже есть DIV и тег P для этой переменной. Моя проблема в том, что длинный текст содержит разрывы строк. Поскольку тег начального абзаца уже существует, я должен преобразовать строку в конец P, а затем новый старт P, см. Заголовок моего сообщения. –

0

ОК ищет некоторые больше к этому я пойду еще дальше. Мой процесс включает в себя XSLT, который разбивает узел <row> на отдельные файлы XML. Будет легче запустить функцию tokenize в этом меньшем XML-файле.

Но я хочу только токенизировать текст только на узлах этого XML, как я могу выбрать именно тот. Я нашел это:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:template match="/excel-row/col"> 
    <xsl:apply-templates/> 
</xsl:template> 
<xsl:template match="text()"> 
    <xsl:for-each select="tokenize(.,'\n')"> 
     <xsl:sequence select="."/> 
     <xsl:if test="not(position() eq last())"> 
      <br /> 
     </xsl:if> 
    </xsl:for-each> 
</xsl:template> 

Узел XML выглядит следующим образом:

<col name="Model descr.">Some text in first paragraph. 
More text in second paragraph. 
And then a third paragraph with more text. 

Тогда мы имеем последний абзац.

Так как я выбираю узел col name="Model descr.">

благодарным за любую помощь, мой опыт XSLT ограничен, как вы видите.

Jan

Смежные вопросы