Модуляризация xslt? - PullRequest
       1

Модуляризация xslt?

2 голосов
/ 30 декабря 2011

Как я могу модулировать повторяющийся набор выходов в преобразовании xslt?Например, у меня есть что-то вроде следующего (псевдокод).

<foreach "path">
  <if "count(/subPath) = 0">
    <a><value-of "x"/></a>
    <b><value-of "y"/></b>
    <c></c>
  </fi>
  <else>
    <foreach "subPath">
      <a><value-of "../x"/></a>
      <b><value-of "../y"/></b>
      <c><value-of "z"/></c>
    </foreach>
  </else>
</foreach>

и мне хотелось бы что-то вроде следующего

<foreach "path">
  <if "count(/subPath) = 0">
     <?/>
  </fi>
  <else>
    <foreach "subPath">
       <?/>
    </foreach>
  </else>
</foreach> 
<?>
   <a><value-of "../x"/></a>
   <b><value-of "../y"/></b>
   <c><value-of "z"/></c>
</?>

Какую конструкцию я ищу?

Ответы [ 3 ]

2 голосов
/ 30 декабря 2011

I. Перевод псевдокода

Ваш псевдокод переводит 1: 1 в это XSLT-преобразование :

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="/">
     <xsl:for-each select="/t/m/n/p">
       <xsl:choose>
        <xsl:when test="not(subPath)">
        <a><xsl:value-of select="x"/></a>
        <b><xsl:value-of select="y"/></b>   
      </xsl:when>
      <xsl:otherwise>
       <xsl:for-each select="subPath">
        <a><xsl:value-of select="../x"/></a>
        <b><xsl:value-of select="../y"/></b>
        <c><xsl:value-of select="z"/></c>   
       </xsl:for-each>
      </xsl:otherwise>
       </xsl:choose>
     </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

при применении к этому XML-документу (в вопросе такой документ не предоставляется !!!):

<t>
 <m>
  <n>
   <p>
     <x>1</x>
     <y>2</y>
     <subPath>
       <z>3</z>
     </subPath>
     <subPath>
       <z>4</z>
     </subPath>
   </p>
  </n>
 </m>
</t>

желаемый, правильный результат получается :

<a>1</a>
<b>2</b>
<c>3</c>
<a>1</a>
<b>2</b>
<c>4</c>

II. Рефакторинг

Это преобразованное эквивалентное преобразование, в котором не используются xsl:for-each или какие-либо явные условные инструкции :

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="p[not(subPath)]" name="processP">
   <xsl:param name="pNode" select="."/>
   <a><xsl:value-of select="$pNode/x"/></a>
   <b><xsl:value-of select="$pNode/y"/></b>
 </xsl:template>

 <xsl:template match="p/subPath">
   <xsl:call-template name="processP">
    <xsl:with-param name="pNode" select=".."/>
   </xsl:call-template>
   <c><xsl:value-of select="z"/></c>    
 </xsl:template>
 <xsl:template match="text()"/>
</xsl:stylesheet>

при применении к тому же XML-документу (см. Выше), снова получается тот же правильный результат :

<a>1</a>
<b>2</b>
<c>3</c>
<a>1</a>
<b>2</b>
<c>4</c>

Do note :

  1. Шаблоны / сопоставление с образцом, чтобы избежать использования явных условных инструкций. Это самый мощный XSLT-специфичный шаблон проектирования.

  2. Повторяющегося кода нет.

  3. Каждый шаблон точно соответствует узлу, который он должен обрабатывать, при точно требуемых условиях.

  4. Код первого шаблона используется повторно, также давая ему имя, чтобы его можно было явно вызывать. Таким образом исключается дублирование кода.

0 голосов
/ 30 декабря 2011

Вы ищете шаблоны (<template>), которые можно вызвать с помощью <call-template>.Дополнительные детали на http://www.w3.org/TR/xslt#named-templates.

0 голосов
/ 30 декабря 2011

Вы, вероятно, ищете именованных шаблонов .

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