Отображать разные атрибуты xsl: в зависимости от окончания строки

У меня есть следующий код xsl в документе xsl

                <A target="_blank" style="text-decoration=none">
                    <xsl:attribute name="href">viewdoc.aspx?doc=<xsl:value-of select="URLFilePath"/>&amp;mode=inline</xsl:attribute>
                        <xsl:attribute name="prefix"><xsl:value-of select="FileName"/>: </xsl:attribute>
          <IMG src="images/word_small.gif" border="0"/>
                </A>

и в коде я делаю это

            newItemNode = xmlDocument.CreateElement("URLFilePath")
            newItemNode.InnerText = correctedPath
            xmlItemNode.ParentNode.AppendChild(newItemNode)

Теперь это отлично работает для документов Word. Однако мне нужен способ в коде, чтобы проверить расширение файла и отобразить правильное изображение и атрибут xsl: в зависимости от оператора If.

Таким образом, оператор If будет выглядеть так:

            If correctedPath.ToLower.Contains(".doc") Then
                 //display the word icon and attributes
            Else
                 //display the excel icon and attributes
            End If

Не могли бы вы дать мне несколько советов и помочь в том, как я могу этого добиться?

Спасибо


person JMon    schedule 30.04.2010    source источник
comment
Хороший вопрос (+1). Смотрите мой ответ для правильного решения. :)   -  person Dimitre Novatchev    schedule 30.04.2010


Ответы (4)


Простое использование contains() может привести к неверным результатам (см. тестовый XML-документ).

Что необходимо, так это ends-with(), которая является стандартной в XPath 2.0 и может быть реализована в XSLT 1.0, как в следующем преобразовании:

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

 <xsl:template match="URLFilePath">
   <xsl:variable name="visDoc">
    <xsl:call-template name="ends-with">
     <xsl:with-param name="pEnding" select="'.doc'"/>
    </xsl:call-template>
   </xsl:variable>
   <xsl:variable name="visXls">
    <xsl:call-template name="ends-with">
     <xsl:with-param name="pEnding" select="'.xls'"/>
    </xsl:call-template>
   </xsl:variable>

   <xsl:choose>
     <xsl:when test="$visDoc=1">word_small.gif</xsl:when>
     <xsl:when test="$visXls=1">xls_small.gif</xsl:when>
     <xsl:otherwise>unknown_small.gif</xsl:otherwise>
   </xsl:choose>
 </xsl:template>

 <xsl:template name="ends-with">
   <xsl:param name="pEnding"/>

   <xsl:value-of select=
    "number(substring(.,
                      string-length() -string-length($pEnding) +1
                      )
    =
     $pEnding
            )
    "/>
 </xsl:template>
</xsl:stylesheet>

Когда это преобразование применяется к следующему тестовому XML-документу:

<files>
 <URLFilePath>myFile.doc</URLFilePath>
 <URLFilePath>myFile.xls</URLFilePath>
 <URLFilePath>myFile.xls.doc</URLFilePath>
 <URLFilePath>myFile.doc.xls</URLFilePath>
</files>

получен правильный результат:

 word_small.gif
 xls_small.gif
 word_small.gif
 xls_small.gif

Обратите внимание, что простое использование contains() приводит к неправильным результатам.

person Dimitre Novatchev    schedule 30.04.2010
comment
Привет, Димитре. На данный момент у меня есть ‹A target=_blank style=text-decoration=none› ‹xsl:attribute name=href›viewdoc.aspx?doc=‹xsl:value-of select=URLFilePath/›mode=inline‹/ xsl:attribute› ‹i18n:popup key=results.open.word› ‹xsl:имя атрибута=префикс›‹xsl:value-of select=FileName/›: ‹/xsl:attribute› - person JMon; 03.05.2010
comment
‹xsl:выбрать› ‹xsl:когда тест=содержит(., '.doc')› ‹IMG src=images/word_small.gif border=0/› ‹/xsl:когда› ‹xsl:когда тест=содержит(. , '.xls')› ‹IMG src=images/excel_small.gif border=0/› ‹/xsl:when› ‹/xsl:choose› ‹/i18n:popup› ‹/A›, и это, похоже, работает. Итак, как я могу адаптироваться к вашему примеру? - person JMon; 03.05.2010
comment
@Johann: Это не работает с XML-документом, который я предоставил в своем ответе: <files> <URLFilePath>myFile.doc</URLFilePath> <URLFilePath>myFile.xls</URLFilePath> <URLFilePath>myFile.xls.doc</URLFilePath> <URLFilePath>myFile.doc.xls</URLFilePath> </files> - person Dimitre Novatchev; 03.05.2010

Мне удалось найти решение! Извините за поздний ответ, но нужно было заняться чем-то другим

Вот код: -

                <A target="_blank" style="text-decoration=none">
          <xsl:choose>
            <xsl:when test="contains(., '.doc')">
              <xsl:attribute name="href">viewdoc.aspx?doc=<xsl:value-of select="URLFilePath"/>&amp;mode=inline
              </xsl:attribute>
                <xsl:attribute name="prefix">
                  <xsl:value-of select="FileName"/>:
                </xsl:attribute>
              <IMG src="images/word_small.gif" border="0"/>
            </xsl:when>
            <xsl:when test="contains(., '.xls')">
              <xsl:attribute name="href">viewxls.aspx?doc=<xsl:value-of select="URLFilePath"/>&amp;mode=inline
              </xsl:attribute>
                <xsl:attribute name="prefix">
                  <xsl:value-of select="FileName"/>:
                </xsl:attribute>
              <IMG src="images/excel_small.gif" border="0"/>
            </xsl:when>
          </xsl:choose>
                </A>

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

person JMon    schedule 10.05.2010

Поздний ответ, но я нашел два ответа, которые касаются сопоставления конца строки с XSLT 1.0 и очень элегантны:

иди поставь им +1

person akostadinov    schedule 06.08.2013

При необходимости это можно сделать исключительно в вашем XSLT-документе. Для отображения изображения вы можете использовать оператор xsl:choose, который проверяет элемент URLFilePath.

<xsl:choose>
   <xsl:when test="contains(., '.doc')">
      <IMG src="images/word_small.gif" border="0"/> 
   </xsl:when> 
   <xsl:when test="contains(., '.xls')">
      <IMG src="images/excel_small.gif" border="0"/> 
   </xsl:when> 
</xsl:choose>

Если вы хотите сделать эту проверку в коде позади, вы всегда можете добавить дополнительные атрибуты к своему элементу URLFilePath.

imageAttr = xmlDocument.CreateAttr("image")     
If correctedPath.ToLower.Contains(".doc") Then
    imageAttr.value = "images/word_small.gif"
Else
    imageAttr.value = "images/excel_small.gif"
End If
newItemNode.AppendChild(imageAttr) 

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

<IMG border="0"> 
   <xsl:attribute name="src"><xsl:value-of select='@image' /></xsl:attribute>
</IMG>
person Tim C    schedule 30.04.2010
comment
Привет, Тим. Большое спасибо за вашу помощь. Что-то вроде этого тоже сработает? - person JMon; 30.04.2010
comment
‹xsl:choose› ‹xsl:when test=contains(., '.doc’)› ‹A target=_blank style=text-decoration=none› ‹xsl:attribute name=href›viewdoc.aspx?doc=‹xsl :value-of select=URLFilePath/›mode=inline‹/xsl:attribute› ‹xsl:имя атрибута=префикс›‹xsl:value-of select=FileName/›: ‹/xsl:attribute› ‹IMG src=images/ word_small.gif border=0/› ‹/A› ‹/xsl:when› - person JMon; 30.04.2010
comment
‹xsl:when test=contains(., '.xls')› ‹A target=_blank style=text-decoration=none› ‹xsl:attribute name=href›viewxls.aspx?doc=‹xsl:value-of select =URLFFilePath/›mode=inline‹/xsl:attribute› ‹xsl:имя атрибута=префикс›‹xsl:value-of select=FileName/›: ‹/xsl:attribute› ‹IMG src=images/excel_small.gif border= 0/› ‹/A› ‹/xsl:когда› ‹/xsl:выбрать› - person JMon; 30.04.2010
comment
Привет Иоганн. Ага, что-то подобное сработает. Вы можете указать любое количество элементов в xsl:when. Однако вы должны стараться избегать повторения кода, используйте xsl:choose только для тех битов, которые отличаются, если можете. - person Tim C; 30.04.2010
comment
contains проверяет только, встречается ли подстрока где-либо в целевой строке, а не появляется ли она в конце целевой строки. - person markusk; 02.05.2010