XSLT: xsl: функция не будет работать - PullRequest
0 голосов
/ 14 июля 2009

У меня работает следующее:

<xsl:variable name="core" select="document('CoreMain_v1.4.0.xsd')" />
<xsl:variable name="AcRec" select="document('AcademicRecord_v1.3.0.xsd')" />

<xsl:template match="xs:element">       
  <xsl:variable name="prefix" select="substring-before(@type, ':')" />
  <xsl:variable name="name" select="substring-after(@type, ':')" />

  <xsl:choose>
    <xsl:when test="$prefix = 'AcRec'">             
      <xsl:apply-templates select="$AcRec//*[@name=$name]">
        <xsl:with-param name="prefix" select="$prefix" />
      </xsl:apply-templates>                
    </xsl:when>
    <xsl:when test="$prefix = 'core'">              
      <xsl:apply-templates select="$core//*[@name=$name]">
        <xsl:with-param name="prefix" select="$prefix" />
      </xsl:apply-templates>                
    </xsl:when>             
  </xsl:choose>
</xsl:template>

Но я использую ту же логику для обработки поиска элементов в текущем или других документах на основе префикса, сопоставляя имя узла во многих местах таблицы стилей. Итак, после изменения версии таблицы стилей на 2.0 я попытался:

<xsl:template match="xs:element">
  <xsl:value-of select="my:lookup(@type)" />
</xsl:template>

<xsl:function name="my:lookup">
  <xsl:param name="attribute" />

  <!-- parse the attribute for the prefix & name values -->
  <xsl:variable name="prefix" select="substring-before($attribute, ':')" />
  <xsl:variable name="name" select="substring-after($attribute, ':')" />

  <!-- Switch statement based on the prefix value -->
  <xsl:choose>
    <xsl:when test="$prefix = 'AcRec'">             
      <xsl:apply-templates select="$AcRec//*[@name=$name]">
        <xsl:with-param name="prefix" select="$prefix" />
      </xsl:apply-templates>                
    </xsl:when>
    <xsl:when test="$prefix = 'core'">              
      <xsl:apply-templates select="$core//*[@name=$name]">
        <xsl:with-param name="prefix" select="$prefix" />
      </xsl:apply-templates>                
    </xsl:when>             
  </xsl:choose> 
</xsl:function>

В моем чтении я нашел только примеры функций, которые возвращают текст - ни один из них не вызывает шаблонов. У меня сложилось впечатление, что функция xsl: всегда должна возвращать текст / вывод ...

После более подробного изучения он входит в функцию my: lookup, и переменные (префикс и имя) заполняются. Таким образом, он вводит оператор xsl: choose и выбирает соответствующий результат при тестировании. Кажется, проблема связана с apply-templates - value-of отображает дочерние значения; copy-of делает то же самое, что я считаю странным (не должен ли вывод включать объявления элементов xml?). Почему будет разница, если код, работающий в объявлении шаблона, будет перемещен в xsl: function?

1 Ответ

2 голосов
/ 15 июля 2009

Прошло много времени с тех пор, как я сделал серьезный XSLT, но IIRC ваша проблема не в функции, а в вашем шаблоне:

<xsl:template match="xs:element">
  <xsl:value-of select="my:lookup(@type)" />
</xsl:template>

Оператор value-of не будет встроен в дерево результатов , возвращаемое вашей функцией. Вместо этого он попытается свести это дерево результатов к какой-то строке, и вместо этого вставить это в строку. Вот почему вы видите дочерние значения, а не сами элементы.

Чтобы встроить дерево результатов, возвращаемое вашей функцией, вам нужно использовать несколько шаблонов, чтобы скопировать дерево результатов на место.

Итак, ваш основной шаблон должен измениться на:

<xsl:template match="xs:element">
  <xsl:apply-templates select="my:lookup(@type)" />
</xsl:template>

и вам понадобятся шаблоны для рекурсивного вызова. Быстрый Google нашел хорошее обсуждение шаблона идентификации , который должен делать то, что вам нужно.

(Прошу прощения за любые синтаксические ошибки, как я уже сказал, это было давно ...)

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