В XSL: как избежать выбора блоков для обтекания элементов? - PullRequest
5 голосов
/ 26 августа 2011

есть случай, который встречается часто.Я анализирую XML и создаю свой документ XHTML с помощью XSLT 1.0.

Case:

/* XML */
<Image src="path-to-img.jpg" href="link-to-page.html" />

/* XSL */
<xsl:choose>
    <xsl:when test="@href">
    <a href="{@href}">
       <img src="{@src}"/>
    </a>
</xsl:when>
<xsl:otherwise>
    <img src="{@src}"/>
</xsl:otherwise>
</xsl:choose>

Вы видите проблему: я просто выбираю случай, если есть набор href.Я не удовлетворен этим подходом, но я не вижу другого варианта для его реализации.

Есть идеи?

Ответы [ 3 ]

7 голосов
/ 26 августа 2011

Способ устранения явных условных инструкций внутри шаблона заключается в использовании сопоставления с шаблоном в шаблоне сопоставления шаблона :

<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="Image[@href]">
    <a href="{@href}">
     <xsl:call-template name="basicImage" />
    </a>
 </xsl:template>

 <xsl:template match="Image" name="basicImage">
   <img src="{@src}"/>
 </xsl:template>
</xsl:stylesheet>

XSLT 2.0: Существует особенно элегантное решение с использованием <xsl:next-match>:

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

 <xsl:template match="Image[@href]">
    <a href="{@href}">
    <xsl:next-match/>
    </a>
 </xsl:template>

 <xsl:template match="Image" name="basicImage">
   <img src="{@src}"/>
 </xsl:template>
</xsl:stylesheet>

Оба преобразования при применении к предоставленному документу XML :

<Image src="path-to-img.jpg" href="link-to-page.html" />

выдаст нужный, правильный результат :

<a href="link-to-page.html">
   <img src="path-to-img.jpg"/>
</a>
2 голосов
/ 26 августа 2011

Чтобы избежать дублирования кода, вы можете использовать именованные шаблоны, содержащие код для рендеринга тега img

<xsl:template name="img">
   <img src="{@src}" />
</xsl:template>

Вы можете назвать это так

<xsl:call-template name="img" />

Итак, готовый XSLT будет

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

   <xsl:output method="xml" indent="yes"/>

   <xsl:template match="/Image ">
      <xsl:choose>
         <xsl:when test="@href">
            <a href="{@href}">
               <xsl:call-template name="img" />
            </a>
         </xsl:when>
         <xsl:otherwise>
            <xsl:call-template name="img" />
         </xsl:otherwise>
      </xsl:choose>
   </xsl:template>

   <xsl:template name="img">
      <img src="{@src}" />
   </xsl:template>
</xsl:stylesheet>

Несмотря на то, что у вас по-прежнему есть две команды xsl: call-template , любые изменения в отображении тега img теперь необходимо выполнять только в одном месте. Вы также можете вызвать этот шаблон из любого места в вашем XSLT, предполагая, что текущий узел - это узел image .

2 голосов
/ 26 августа 2011

Опция # 1 вы можете создать безусловное a и изображение ниже и использовать атрибут xsl:if append (обратите внимание, что в этом случае есть некоторый недостаток - всегда существует тег a, но без href - для конечного пользователя этоне проблема):

<a>
   <xsl:if test="@href">
      <xsl:attribute name="href" value="{@href}"/>
   </xsl:if>
   <img src="{@src}"/>

</a>

Вариант № 2 Если применим javascript - просто поместите для обработки img onclick

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