Параметры условного оператора XSLT

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

Он просто ищет href в первом случае, и если присутствует вход href, соответствующее изображение со ссылкой отобразит вывод + alt tag. Если отсутствует ввод href, просто само изображение будет отображать вывод + alt tag.

Он отлично работает для конкретной цели, хотя выглядит и чувствует себя немного неуклюжим.

Поэтому я хочу знать, есть ли более чистый или умный способ достижения результата.

Любой совет будет принята с благодарностью.

Спасибо, озмо

Anyhoo, вот мой шедевр...

      <!-- SUPPORTING IMAGE HREF CONDITIONAL -->
      <xsl:choose>
        <xsl:when test="SupportingImageLink/a/@href !=''">
          <tr>
            <td>
              <a href="{SupportingImageLink/a/@href}">
                <img src="{SupportingImage/img/@src}" width="680" alt="{SupportingImage/img/@alt}" style="border: 0;width: 100%;max-width: 680px;" class="center-on-narrow"></img>
              </a>
            </td>
          </tr>
        </xsl:when>
        <xsl:otherwise>
          <tr>
            <td>
                <img src="{SupportingImage/img/@src}" width="680" alt="{SupportingImage/img/@alt}" style="border: 0;width: 100%;max-width: 680px;" class="center-on-narrow"></img>
            </td>
          </tr>
        </xsl:otherwise>
      </xsl:choose>
      <!-- SUPPORTING IMAGE HREF CONDITIONAL : END -->

И, как и просили, это урезанный XML...

<root>
  <Title>New layout test</Title>
  <Edition>Octovember 2019</Edition>
  <Notification>
  <Body>Warning Warning Warning Will Robinson!! Aliens Aliens Aliens everywhere!</Body>
  </Notification>
  <Introduction>
    <Heading>Squids attack!</Heading>
    <Body>Ugh tacos artisan, single-origin coffee jianbing hoodie skateboard. 90's unicorn next level fixie. Glossier coloring book drinking vinegar, health goth flexitarian activated charcoal yuccie hexagon whatever normcore bushwick ethical mustache plaid lyft. Chicharrones edison bulb vinyl disrupt tbh glossier, marfa mumblecore four loko +1 leggings.</Body>
  </Introduction>
  <Section>
    <Heading>Just in - Cyborg bears attacking!</Heading>
    <Structure>3</Structure>
    <SupportingImage>
      <img src="/uploadedImages/dev/robots.png?n=3082" alt="Will Robinson" title="Will Robinson" style="width: 680px; height: 283px;" align="left" width="680" height="283" />
    </SupportingImage>
    <SupportingImageLink>
      <a href="http://www.squids-attack/cyb-bears.html">AAARRRRGGGGHHHH!!!</a>
    </SupportingImageLink>
    <Body>Ugh tacos artisan, single-origin coffee jianbing hoodie skateboard. 90's unicorn next level fixie. Glossier coloring book drinking vinegar, health goth flexitarian activated charcoal yuccie hexagon whatever normcore bushwick ethical mustache plaid lyft. Chicharrones edison bulb vinyl disrupt tbh glossier, marfa mumblecore four loko +1 leggings. Knausgaard af YOLO, direct trade drinking vinegar try-hard williamsburg roof party asymmetrical snackwave waistcoat. Venmo food truck next level raw denim, pabst photo booth quinoa chambray art party hot chicken cliche tote bag polaroid direct trade whatever. Shabby chic lomo locavore slow-carb leggings.</Body>
    <Button>More information</Button>
  </Section>
</root>

3 ответа

Решение

Вполне возможно написать код XSLT без каких-либо условных инструкций.

На самом деле это рекомендуемая СУХАЯ практика!

  <xsl:template match="Section/SupportingImageLink">
    <tr>
      <td>
        <xsl:apply-templates select="a[@href !='']"/>
        <xsl:apply-templates select="self::*[not(a[@href !=''])]" mode="getImage"/>
      </td> 
    </tr>
  </xsl:template>

  <xsl:template match="SupportingImageLink/a[@href !='']/text()">
    <xsl:apply-templates select="." mode="getImage"/>
  </xsl:template>

  <xsl:template match="node()" mode="getImage">
    <xsl:param name="pImg" select="ancestor::Section[1]/SupportingImage/img"/>
     <img src="{$pImg/@src}" width="680" 
      alt="{$pImg/@alt}" style="border: 0;width: 100%;max-width: 680px;" 
      class="center-on-narrow"></img>
  </xsl:template>

Вот полное преобразование, реализующее этот самый фундаментальный шаблон проектирования XSLT: использование и переопределение правила идентификации:

<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="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="Section/SupportingImageLink">
    <tr>
      <td>
        <xsl:apply-templates select="a[@href !='']"/>
        <xsl:apply-templates select="self::*[not(a[@href !=''])]" mode="getImage"/>
      </td> 
    </tr>
  </xsl:template>

  <xsl:template match="SupportingImageLink/a[@href !='']/text()">
    <xsl:apply-templates select="." mode="getImage"/>
  </xsl:template>

  <xsl:template match="node()" mode="getImage">
    <xsl:param name="pImg" select="ancestor::Section[1]/SupportingImage/img"/>
     <img src="{$pImg/@src}" width="680" 
      alt="{$pImg/@alt}" style="border: 0;width: 100%;max-width: 680px;" 
      class="center-on-narrow"></img>
  </xsl:template>
</xsl:stylesheet>

Когда это преобразование применяется к следующему документу XML (предоставленному с дополнительным SupportingImageLink элемент, который не имеет связи с href атрибут:

<root>
  <Title>New layout test</Title>
  <Edition>Octovember 2019</Edition>
  <Notification>
  <Body>Warning Warning Warning Will Robinson!! Aliens Aliens Aliens everywhere!</Body>
  </Notification>
  <Introduction>
    <Heading>Squids attack!</Heading>
    <Body>Ugh tacos artisan, single-origin coffee jianbing hoodie skateboard. 
    90's unicorn next level fixie. Glossier coloring book drinking vinegar, 
    health goth flexitarian activated charcoal yuccie hexagon whatever 
    normcore bushwick ethical mustache plaid lyft. Chicharrones edison 
    bulb vinyl disrupt tbh glossier, marfa mumblecore four loko +1 leggings.</Body>
  </Introduction>
  <Section>
    <Heading>Just in - Cyborg bears attacking!</Heading>
    <Structure>3</Structure>
    <SupportingImage>
      <img src="/uploadedImages/dev/robots.png?n=3082" alt="Will Robinson" 
           title="Will Robinson" style="width: 680px; height: 283px;" 
           align="left" width="680" height="283" />
    </SupportingImage>
    <SupportingImageLink>
      <a href="http://www.squids-attack/cyb-bears.html">AAARRRRGGGGHHHH!!!</a>
    </SupportingImageLink>
    <SupportingImageLink>
      <a>AAARRRRGGGGHHHH!!!</a>
    </SupportingImageLink>
    <Body>Ugh tacos artisan, single-origin coffee jianbing hoodie skateboard.
     90's unicorn next level fixie. Glossier coloring book drinking vinegar, 
     health goth flexitarian activated charcoal yuccie hexagon whatever normcore 
     bushwick ethical mustache plaid lyft. Chicharrones edison bulb vinyl 
     disrupt tbh glossier, marfa mumblecore four loko +1 leggings. Knausgaard
      af YOLO, direct trade drinking vinegar try-hard williamsburg roof party 
      asymmetrical snackwave waistcoat. Venmo food truck next level raw denim, 
      pabst photo booth quinoa chambray art party hot chicken cliche tote bag 
      polaroid direct trade whatever. Shabby chic lomo locavore slow-carb leggings.</Body>
    <Button>More information</Button>
  </Section>
</root>

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

<root>
  <Title>New layout test</Title>
  <Edition>Octovember 2019</Edition>
  <Notification>
      <Body>Warning Warning Warning Will Robinson!! Aliens Aliens Aliens everywhere!</Body>
  </Notification>
  <Introduction>
      <Heading>Squids attack!</Heading>
      <Body>Ugh tacos artisan, single-origin coffee jianbing hoodie skateboard. 
    90's unicorn next level fixie. Glossier coloring book drinking vinegar, 
    health goth flexitarian activated charcoal yuccie hexagon whatever 
    normcore bushwick ethical mustache plaid lyft. Chicharrones edison 
    bulb vinyl disrupt tbh glossier, marfa mumblecore four loko +1 leggings.</Body>
  </Introduction>
  <Section>
      <Heading>Just in - Cyborg bears attacking!</Heading>
      <Structure>3</Structure>
      <SupportingImage>
         <img src="/uploadedImages/dev/robots.png?n=3082" alt="Will Robinson"
              title="Will Robinson"
              style="width: 680px; height: 283px;"
              align="left"
              width="680"
              height="283"/>
      </SupportingImage>
      <tr>
         <td>
            <a href="http://www.squids-attack/cyb-bears.html">
               <img src="/uploadedImages/dev/robots.png?n=3082" width="680" alt="Will Robinson"
                    style="border: 0;width: 100%;max-width: 680px;"
                    class="center-on-narrow"/>
            </a>
         </td>
      </tr>
      <tr>
         <td>
            <img src="/uploadedImages/dev/robots.png?n=3082" width="680" alt="Will Robinson"
                 style="border: 0;width: 100%;max-width: 680px;"
                 class="center-on-narrow"/>
         </td>
      </tr>
      <Body>Ugh tacos artisan, single-origin coffee jianbing hoodie skateboard.
     90's unicorn next level fixie. Glossier coloring book drinking vinegar, 
     health goth flexitarian activated charcoal yuccie hexagon whatever normcore 
     bushwick ethical mustache plaid lyft. Chicharrones edison bulb vinyl 
     disrupt tbh glossier, marfa mumblecore four loko +1 leggings. Knausgaard
      af YOLO, direct trade drinking vinegar try-hard williamsburg roof party 
      asymmetrical snackwave waistcoat. Venmo food truck next level raw denim, 
      pabst photo booth quinoa chambray art party hot chicken cliche tote bag 
      polaroid direct trade whatever. Shabby chic lomo locavore slow-carb leggings.</Body>
      <Button>More information</Button>
  </Section>
</root>

Я бы написал это как шаблон:

<xsl:template match="/SupportingImageLink/img">
    <img src="@src" alt="@alt" width="680" .../>
</xsl:template>

а также

<tr>
    <td>
         <xsl:apply-templates select="SupportingImageLink/node()"/>
    </td>
</tr>

E&OE

Обратите внимание, что ваша часть привязки произойдет сама по себе с помощью правила копирования по умолчанию.

Ваш вопрос может быть дан ответ в первую очередь на основе мнения разработчиков. Это не очень хорошая вещь на SO. Если мы говорим о производительности или ремонтопригодности, не будет и не может быть столько основанного на мнениях материала. Если это работает быстрее, это быстрее!

Изученные в книге "XSLT 2.0 и XPATH 2.0 4-е издание", опубликованной wrox милым мистером Майклом Кей, есть шаблоны проектирования, которые вы можете использовать:

Заполните бланки таблиц стилей

Посмотрите и почувствуйте HTML и не используйте всю мощь XSLT. Документ в основном HTML, а также некоторые xslt-теги для получения динамического контента, например, через <xsl:value-of .. Вид вашего стиля в этом конкретном проекте.

Навигационная таблица стилей

В дополнение к заполнению бланков он идет в направлении "программирования". Аутсорсинговые задачи в именованных шаблонах, например <xsl:template name="renderImage", Делайте больше магии, чем просто выводите значение элемента.

Таблица стилей на основе правил

Ваша главная задача - преобразовать xml в выходную цель. Он может варьироваться от простого текста до xml, проверяется на соответствие любой схеме json. Вы в основном пишете шаблоны, как <xsl:template match="img" а также <xsl:template match="a".., Вы создаете наборы правил, которые называются <xsl:apply-templates />-заявления. Вы, скорее, говорите: ищите правила для этого узла (-set) и смотрите, какие правила там определены, чем командуйте процессору xslt, например, "действительно вызывайте этот именованный шаблон сейчас, а после этого вызывайте этот именованный шаблон".

Вычислительная таблица стилей

Позволяет усложнить и использовать всю мощь функций XSLT и записи, переупорядочить исходное дерево в целевое дерево, создать узлы и сделать это с несколькими исходными и целевыми файлами. Теперь вам нужно понять концепцию функционального программирования и выйти за горизонт.

Другие вопросы по тегам