использование xml в качестве переменной xsl

Мне нужно создать слегка динамический pdf (две переменные) с двумя текстовыми блоками на разных языках.

Большая часть текста в обоих блоках статична.

Я подумал, могу ли я создать один шаблон, который будет создавать xsl-fo для макета. Затем создайте две переменные, содержащие пользовательский xml. Что-то типа:

<xsl:variable name="TEXT_CONTENT_ENG" >
  <STATIC_TEXT> 
   <LABEL>Hello</LABEL>
   <REQUEST>Please pay your bill before </REQUEST>
  </STATIC_TEXT>
</xsl:variable>

Наконец, я смог дважды применить созданный шаблон, используя эти переменные.

xsl, похоже, проверяет заданную переменную, но я не смог применить шаблон к этому xml. Пробовал, а также документ ($ TEXT_CONTENT_ENG) не работал.

Возможно ли это вообще и как это сделать?


person Priit    schedule 20.10.2010    source источник


Ответы (3)


Большая часть текста в обоих блоках статична.

Если это так, то правильным способом XSLT являются встроенные данные. Из http://www.w3.org/TR/xslt#stylesheet-element

Кроме того, элемент xsl:stylesheet может содержать любой элемент, не входящий в пространство имен XSLT, при условии, что расширенное имя элемента имеет ненулевой URI пространства имен. Наличие таких элементов верхнего уровня не должно изменять поведение элементов и функций XSLT, определенных в этом документе; например, такому элементу верхнего уровня не разрешалось бы указывать, что xsl:apply-templates должен использовать разные правила для разрешения конфликтов. Таким образом, процессор XSLT всегда может игнорировать такие элементы верхнего уровня и должен игнорировать элемент верхнего уровня без выдачи ошибки, если он не распознает URI пространства имен. Такие элементы могут обеспечивать, например,

  • информация, используемая элементами расширения или функциями расширения (см.
    [14 Extensions]),

  • информация о том, что делать с деревом результатов,

  • информация о том, как получить исходное дерево,

  • метаданные о таблице стилей,

  • структурированная документация для таблицы стилей.

<stylesheet version="1.0" xmlns="http://www.w3.org/1999/XSL/Transform">
    <variable name="vRTF">
        <STATIC_TEXT xmlns="">
            <LABEL>Hello</LABEL>
            <REQUEST>Please pay your bill before </REQUEST>
        </STATIC_TEXT>
    </variable>
    <template match="/">
        <apply-templates
              select="document('')/*/xsl:variable[@name='vRTF']/node()"
              xmlns:xsl="http://www.w3.org/1999/XSL/Transform"/>
    </template>
    <template match="@*|node()">
        <copy>
            <apply-templates select="@* | node()"/>
        </copy>
    </template>
</stylesheet>

Вывод:

<STATIC_TEXT>
    <LABEL>Hello</LABEL>
    <REQUEST>Please pay your bill before </REQUEST>
</STATIC_TEXT>

Примечание. В XML 1.0 можно сбросить только пространство имен по умолчанию.

person Community    schedule 20.10.2010

Ответ Алехандро в целом правильный, но нетрадиционное использование пространств имен немного сбивает с толку, и он завернул данные в ненужный элемент xsl:variable, что тоже немного сбивает с толку.

Пока вы помещаете свой элемент в его собственное пространство имен, вы можете сделать его дочерним элементом элемента xsl:stylesheet. Затем вы можете получить к нему доступ, используя document(''), который возвращает текущий документ XSLT:

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:in="urn:inline-data"
    exclude-result-prefixes="in"
>

   <in:TEXT_CONTENT_ENG>
      <STATIC_TEXT> 
         <LABEL>Hello</LABEL>
         <REQUEST>Please pay your bill before </REQUEST>
      </STATIC_TEXT>
   </in:TEXT_CONTENT_ENG>

   <xsl:template match="/">
      <output>
         <xsl:apply-templates 
             select="document('')/xsl:stylesheet/in:TEXT_CONTENT_ENG/*"/>
      </output>
   </xsl:template>

   <xsl:template match="STATIC_TEXT">
      <xsl:text>The label is </xsl:text>
      <xsl:value-of select="LABEL"/>
      <xsl:text> and the request is </xsl:text>
      <xsl:value-of select="REQUEST"/>
   </xsl:template>

</xsl:stylesheet>
person Robert Rossney    schedule 20.10.2010
comment
Насчет нетрадиционного использования пространств имен, ja! Помимо того, что использование пространства имен XSLT в качестве пространства имен по умолчанию не является нетрадиционным, в своем ответе вы используете строковые значения. Вот почему вы не имеете дело с типичной проблемой пространства имен со встроенными данными: несмотря на то, что оно может находиться в нулевом пространстве имен (с родителем в ненулевом пространстве имен), все пространства имен области видимости (возможно, объявленные в элементе stylesheet) существуют . Только с XML 1.1 вы могли сбросить эти объявления пространств имен как xmlns:xsl="". - person ; 21.10.2010
comment
Я должен был сказать, что нетрадиционное использование пространства имен XSLT по умолчанию, на самом деле - ваш пример буквально первый раз, когда я когда-либо видел, чтобы кто-то так делал. Тем не менее, я не понимаю, что вы говорите о типичной проблеме с пространством имен. Что это за проблема? - person Robert Rossney; 21.10.2010

Используя xalan, я смог сделать это так:

<xsl:apply-templates select="xalan:nodeset($TEXT_CONTENT_ENG)/STATIC_TEXT"/>

Аналогичная функция также доступна для exslt

person Priit    schedule 20.10.2010
comment
Для этого вам не нужно использовать функцию *:nodeset(), см.: stackoverflow.com/questions/3626118/xslt-creating-a-map-in-xslt/ - person Per T; 20.10.2010