UMIhelp

Разработка сайта на UMI.CMS => Шаблоны XSLT => Тема начата: Axiomateria от 17 Сентября 2013, 12:28:30

Название: Вывод нескольких элементов справочника через запятую и в конце с точкой
Отправлено: Axiomateria от 17 Сентября 2013, 12:28:30
Здравствуйте!
В объекте каталога (гостиница) подключен справочник со множественным выбором "Ближайшее метро", где элементы соответственно станции метрополитена.
Вопрос: не могу решить вывод нескольких выбранных станций с перечислением их через запятую и в конце с точкой что б.

Пробовал применить шаблон  из файла object-view.xsl (цитирую не полностью)
   <xsl:template match="property" mode="div">
      <xsl:apply-templates select="document(concat('utype://', ../../../@type-id, '.', ../@name))/udata/group/field[@name = ./@name]/tip" mode="tip" />
      <xsl:value-of select="title" />
      <xsl:text>: </xsl:text>
      <span umi:field-name="{@name}"><xsl:apply-templates select="." /></span>
      <xsl:text>; </xsl:text>
   </xsl:template>
   
   <xsl:template match="property[last()]" mode="div">
      <xsl:apply-templates select="document(concat('utype://', ../../../@type-id, '.', ../@name))/udata/group/field[@name = ./@name]/tip" mode="tip" />
      <xsl:value-of select="title" />
      <xsl:text>: </xsl:text>
      <span umi:field-name="{@name}"><xsl:apply-templates select="." /></span>
      <xsl:text>. </xsl:text>
   </xsl:template>

НО как-то не задалось.
 
Название: Re:Вывод нескольких элементов справочника через запятую и в конце с точкой
Отправлено: NOIRMAN от 17 Сентября 2013, 15:35:23
Не уверен точно, но может надо position()=last() ?
Название: Re:Вывод нескольких элементов справочника через запятую и в конце с точкой
Отправлено: Axiomateria от 28 Сентября 2013, 12:56:45
Не уверен точно, но может надо position()=last() ?
то есть в эту строчку <xsl:template match="property[last()]" mode="div">
надо вставить  position()=last()
?
Название: Re:Вывод нескольких элементов справочника через запятую и в конце с точкой
Отправлено: Aisamiery от 28 Сентября 2013, 16:34:39
Не уверен точно, но может надо position()=last() ?
то есть в эту строчку <xsl:template match="property[last()]" mode="div">
надо вставить  position()=last()
?

да
Название: Re:Вывод нескольких элементов справочника через запятую и в конце с точкой
Отправлено: Aisamiery от 28 Сентября 2013, 16:37:35
Ой то есть смотри

Это для всех элементов
<xsl:template match="//property[@name = 'то что нужно' ]">
    элемент, (запятая)
</xsl:template>

Это для последнего
<xsl:template match="//property[@name = 'то что нужно' ] and position() = last()">
    элемент. (точка)
</xsl:template>
Название: Re:Вывод нескольких элементов справочника через запятую и в конце с точкой
Отправлено: admin от 29 Сентября 2013, 11:38:17
Ой то есть смотри

Это для всех элементов
<xsl:template match="//property[@name = 'то что нужно' ]">
    элемент, (запятая)
</xsl:template>

Это для последнего
<xsl:template match="//property[@name = 'то что нужно' ] and position() = last()">
    элемент. (точка)
</xsl:template>

Скорее, вот так:
<xsl:template match="//property[@name = 'то что нужно' ]">
    элемент, (запятая)
</xsl:template>
<xsl:template match="//property[@name = 'то что нужно' and position() = last()]">
    элемент. (точка)
</xsl:template>
Название: Re:Вывод нескольких элементов справочника через запятую и в конце с точкой
Отправлено: Axiomateria от 30 Сентября 2013, 13:20:21
Скорее, вот так:
<xsl:template match="//property[@name = 'то что нужно' ]">
    элемент, (запятая)
</xsl:template>
<xsl:template match="//property[@name = 'то что нужно' and position() = last()]">
    элемент. (точка)
</xsl:template>

И снова у меня непруха,..
В шаблоне у меня вот такое:   
<xsl:template match="udata" mode="hotel-object-view">	 
<xsl:apply-templates select=".//property[@name = 'nearest_metro_station_spb']/value/item/@name" mode="metro_station_list" />
</xsl:template>

<xsl:template match="//property[@name = 'nearest_metro_station_spb' ]" mode="metro_station_list">
       <xsl:value-of select="name" /><xsl:text>, </xsl:text>
</xsl:template>
<xsl:template match="//property[@name = 'nearest_metro_station_spb' and position() = last()]" mode="metro_station_list">
       <xsl:value-of select="name" /><xsl:text>.</xsl:text>
</xsl:template>
- в результате чего названия станций метро успешно выводятся, НО без знаков пунктуации....
Название: Re:Вывод нескольких элементов справочника через запятую и в конце с точкой
Отправлено: admin от 30 Сентября 2013, 13:49:10
шаблон который указывает где выводить запятую, а где нет работает с узлом property, а вызов apply-templates вызывает property/value/item/@name

P.S. это самые основы xslt, еще раз внимательно проработайте цепочку шаблонов

P.P.S. в шаблоне для вывода станции вы работаете с узлом name, который якобы выведет вам название станции, хотя название станции храниться у вас в property/value/item/@name.... соответственно в шаблоне который работет с узлом property для вывода названия станции надо обращаться к value/item/@name

P.P.P.S В вашем случае, apply-templates должен перебирать property/value/item и шаблоны должны быть соответственно не для property, а для item
Название: Re:Вывод нескольких элементов справочника через запятую и в конце с точкой
Отправлено: Axiomateria от 30 Сентября 2013, 14:21:42
шаблон который указывает где выводить запятую, а где нет работает с узлом property, а вызов apply-templates вызывает property/value/item/@name

P.S. это самые основы xslt, еще раз внимательно проработайте цепочку шаблонов

P.P.S. в шаблоне для вывода станции вы работаете с узлом name, который якобы выведет вам название станции, хотя название станции храниться у вас в property/value/item/@name.... соответственно в шаблоне который работет с узлом property для вывода названия станции надо обращаться к value/item/@name

P.P.P.S В вашем случае, apply-templates должен перебирать property/value/item и шаблоны должны быть соответственно не для property, а для item

Я доработал шаблон до такого состояния и теперь запятые показываются после названия станции:
     <xsl:template match="//property[@name = 'nearest_metro_station_spb' ]/value/item/@name" mode="metro_station_list">
       <xsl:value-of select="." /><xsl:text>, </xsl:text>
     </xsl:template>
     <xsl:template match="//property[@name = 'nearest_metro_station_spb' and position() = last()]/value/item/@name" mode="metro_station_list">
       <xsl:value-of select="." /><xsl:text>.</xsl:text>
     </xsl:template>

Однако точки после последнего названия станции нет и вместо точки запятая...
Название: Re:Вывод нескольких элементов справочника через запятую и в конце с точкой
Отправлено: admin от 30 Сентября 2013, 14:42:18
попробуйте работать с item, а не @name, или для наглядности выведите в каждом шаблоне position() для  каждого элемента.
Название: Re:Вывод нескольких элементов справочника через запятую и в конце с точкой
Отправлено: Axiomateria от 08 Октября 2013, 21:29:27
попробуйте работать с item, а не @name, или для наглядности выведите в каждом шаблоне position() для  каждого элемента.

Вы имеете ввиду работать здесь:
<xsl:apply-templates select=".//property[@name = 'nearest_metro_station_msk']/value/item/@name" mode="metro_station_list" />
или здесь:
     <xsl:template match="//property[@name = 'nearest_metro_station_spb' ]/value/item/@name" mode="metro_station_list">
       <xsl:value-of select="." /><xsl:text>, </xsl:text>
     </xsl:template>
     <xsl:template match="//property[@name = 'nearest_metro_station_spb' and position() = last()]/value/item/@name" mode="metro_station_list">
       <xsl:value-of select="." /><xsl:text>.</xsl:text>
     </xsl:template>
?
Проблема просто в том, что система в упор не видит вот эту часть:
     <xsl:template match="//property[@name = 'nearest_metro_station_msk' and position() = last()]/value/item/@name" mode="metro_station_list">
       <xsl:value-of select="." /><xsl:text>.</xsl:text>
     </xsl:template>
Название: Re:Вывод нескольких элементов справочника через запятую и в конце с точкой
Отправлено: admin от 08 Октября 2013, 23:16:31
ваш предыдущий шаблон был почти верен

<xsl:template match="udata" mode="hotel-object-view">	 
<xsl:apply-templates select=".//property[@name = 'nearest_metro_station_spb']/value/item/@name" mode="metro_station_list" />
</xsl:template>

<xsl:template match="//property[@name = 'nearest_metro_station_spb' ]" mode="metro_station_list">
       <xsl:value-of select="name" /><xsl:text>, </xsl:text>
</xsl:template>
<xsl:template match="//property[@name = 'nearest_metro_station_spb' and position() = last()]" mode="metro_station_list">
       <xsl:value-of select="name" /><xsl:text>.</xsl:text>
</xsl:template>

только в нем вам надо было поменять select при вызове и match при обработке.
<xsl:template match="udata" mode="hotel-object-view">	 
<xsl:apply-templates select=".//property[@name = 'nearest_metro_station_spb']/value/item" mode="metro_station_list" />
</xsl:template>

<xsl:template match="item" mode="metro_station_list">
       <xsl:value-of select="name" /><xsl:text>, </xsl:text>
</xsl:template>
<xsl:template match="item[position() = last()]" mode="metro_station_list">
       <xsl:value-of select="name" /><xsl:text>.</xsl:text>
</xsl:template>

Проверьте, заработает ли у вас такой код и разобравшись, отпишите сюда, в чем была ваша ошибка.
Название: Re:Вывод нескольких элементов справочника через запятую и в конце с точкой
Отправлено: Axiomateria от 09 Октября 2013, 00:50:51
в нем вам надо поменять select при вызове и match при обработке.
<xsl:template match="udata" mode="hotel-object-view">	 
<xsl:apply-templates select=".//property[@name = 'nearest_metro_station_spb']/value/item" mode="metro_station_list" />
</xsl:template>

<xsl:template match="item" mode="metro_station_list">
       <xsl:value-of select="name" /><xsl:text>, </xsl:text>
</xsl:template>
<xsl:template match="item[position() = last()]" mode="metro_station_list">
       <xsl:value-of select="name" /><xsl:text>.</xsl:text>
</xsl:template>

Проверьте, заработает ли у вас такой код и разобравшись, отпишите сюда, в чем была ваша ошибка.

Проверил - вставил на замену ваши правки и в результате теперь стали выводиться только запятые и точки, а вот названия самих станций нету...
Название: Re:Вывод нескольких элементов справочника через запятую и в конце с точкой
Отправлено: admin от 09 Октября 2013, 01:41:41
согласен, не досмотрел, надо было вставить @
<xsl:template match="udata" mode="hotel-object-view">	 
<xsl:apply-templates select=".//property[@name = 'nearest_metro_station_spb']/value/item" mode="metro_station_list" />
</xsl:template>

<xsl:template match="item" mode="metro_station_list">
       <xsl:value-of select="@name" /><xsl:text>, </xsl:text>
</xsl:template>
<xsl:template match="item[position() = last()]" mode="metro_station_list">
       <xsl:value-of select="@name" /><xsl:text>.</xsl:text>
</xsl:template>
Название: Re:Вывод нескольких элементов справочника через запятую и в конце с точкой
Отправлено: Axiomateria от 09 Октября 2013, 10:48:06
согласен, не досмотрел, надо было вставить @

Отлично! Спасибо - всё получилось!
Название: Re:Вывод нескольких элементов справочника через запятую и в конце с точкой
Отправлено: admin от 09 Октября 2013, 10:51:57
А теперь уделите некоторое время, чтобы разобраться и написать нам своими словами почему, то что было у вас, не работало.
Название: Re:Вывод нескольких элементов справочника через запятую и в конце с точкой
Отправлено: Axiomateria от 09 Октября 2013, 11:07:47
А теперь уделите некоторое время, чтобы разобраться и написать нам своими словами почему, то что было у вас, не работало.
Отчитаюсь пока вкратце: нет уверенного пока опыта чтения xml версии страницы и следственно карявые выводы в шаблонах получаются - пока не научился видеть очевидное в xml. ВОТ кабы  инструкция была бы наглядная для таких и подобных случаев.... То есть буквально руководство типа "Если надо вывести несколько значений справочника через запятую с точкой в конце перечисления, то надо делать следующее: и далее по тексту да по порядку".
А пока вот новый всплывший косячёк на эту же тему:
Если выделить в списке множественного выбора при редактировании карточки отеля более двух станции метро, то получается буквально такое (выделено три станции)
"Ближайшая ст. Метро: Аэропорт, Ближайшая ст. Метро: Полежаевская, Сокол."

То есть я добавил в шаблон  <xsl:text>Ближайшая ст. Метро: </xsl:text>
     <xsl:template match="item" mode="metro_station_list">
       <xsl:text>Ближайшая ст. Метро: </xsl:text> <xsl:value-of select="@name" /><xsl:text>, </xsl:text>
     </xsl:template>
     <xsl:template match="item[position() = last()]" mode="metro_station_list">
       <xsl:value-of select="@name" /><xsl:text>.</xsl:text>
     </xsl:template>
С одной или двумя названиями станции всё правильно.
Название: Re:Вывод нескольких элементов справочника через запятую и в конце с точкой
Отправлено: Axiomateria от 17 Октября 2013, 14:35:26
После просмотра записи с последнего вэбинара попробовал использовать такой вот вариант, где
подпись: "Ближайшая ст. Метро:" по идее должна перестать быть статичной
    
<xsl:template match="property[@name='nearest_metro_station_spb']"  mode="metro_station_list">        
            <xsl:choose>
                <xsl:when test=".//property[@name = 'nearest_metro_station_spb']/value/item">            
          Метро: <span><xsl:value-of select="@name" /><xsl:text>, </xsl:text></span>
           </xsl:when>
                <xsl:when test="item[position(.//property[@name = 'nearest_metro_station_spb']/value/item) = last()]">            
          <span><xsl:value-of select="@name" /><xsl:text>.</xsl:text></span>
           </xsl:when>
           <xsl:otherwise>
          <xsl:text>Ближайшая ст. Метро: </xsl:text> <span><xsl:text>далее, чем 5 км.</xsl:text> </span>
           </xsl:otherwise>
            </xsl:choose>
    </xsl:template>
Но не сработало.... названия станций не выводятся с этим вариантом.
Название: Re:Вывод нескольких элементов справочника через запятую и в конце с точкой
Отправлено: admin от 17 Октября 2013, 17:48:54
После просмотра записи с последнего вэбинара попробовал использовать такой вот вариант, где
подпись: "Ближайшая ст. Метро:" по идее должна перестать быть статичной
    
<xsl:template match="property[@name='nearest_metro_station_spb']"  mode="metro_station_list">        
            <xsl:choose>
                <xsl:when test=".//property[@name = 'nearest_metro_station_spb']/value/item">            
          Метро: <span><xsl:value-of select="@name" /><xsl:text>, </xsl:text></span>
           </xsl:when>
                <xsl:when test="item[position(.//property[@name = 'nearest_metro_station_spb']/value/item) = last()]">            
          <span><xsl:value-of select="@name" /><xsl:text>.</xsl:text></span>
           </xsl:when>
           <xsl:otherwise>
          <xsl:text>Ближайшая ст. Метро: </xsl:text> <span><xsl:text>далее, чем 5 км.</xsl:text> </span>
           </xsl:otherwise>
            </xsl:choose>
    </xsl:template>
Но не сработало.... названия станций не выводятся с этим вариантом.

если вы пишите шаблон с таким match
<xsl:template match="property[@name='nearest_metro_station_spb']"  mode="metro_station_list"> 

то внутри этого шаблона вы работает от этого match, то есть от property и для получения доступа к узлу value вам надо писать не
.//property[@name = 'nearest_metro_station_spb']/value , а просто value    

Если знать основы с чем вы работает в шаблоне с учетом того что прописанно в match этого шаблона и представлять xml c которым вы работаете, а он выглядит примерно так:
<property id="435" name="nearest_metro_station_spb" type="relation" multiple="multiple">
<title>Ближайшее метро</title>
<value>
<item id="111" name="Аэропорт" type-id="12" ownerId="44" xlink:href="uobject://111"/>
<item id="112" name="Полежаевская, Сокол" type-id="12" ownerId="44" xlink:href="uobject://112"/>
</value>
</property>
 

, то я теряюсь в попытке еще как то по другому объяснить это.



По поводу предыдущей задачи, все точно также, вы прописываете "Ближайшая станция:" не в том шаблоне, почему и получаете результат "Ближайшая ст. Метро: Аэропорт, Ближайшая ст. Метро: Полежаевская, Сокол."

Привожу шаблоны с комментариями.
<xsl:template match="udata" mode="hotel-object-view">	 
<!--
тут мы выбираем все item, то есть получаем такой xml

<item id="111" name="Аэропорт" type-id="12" ownerId="44" xlink:href="uobject://111"/>
<item id="112" name="Полежаевская, Сокол" type-id="12" ownerId="44" xlink:href="uobject://112"/>

и именно пере проработкой всех item и надо выводить строчку "Ближайшее метро:"
-->

<xsl:apply-templates select=".//property[@name = 'nearest_metro_station_spb']/value/item" mode="metro_station_list" />
</xsl:template>

<xsl:template match="item" mode="metro_station_list">
    <xsl:value-of select="@name" /><xsl:text>, </xsl:text>
<!--тут мы обрабатываем все item кроме последнего и если сюда приписать слово "Ближайшее метро:", то мы получим его около кадого пункта кроме последнего, так как последний item обрабатывается шаблоном ниже
-->
</xsl:template>
<xsl:template match="item[position() = last()]" mode="metro_station_list">
    <xsl:value-of select="@name" /><xsl:text>.</xsl:text>
</xsl:template>

P.S. и до тех пор пока вы не проясните для себя вопрос как работать с <xsl:apply-templates> и <xsl:template> или не объясните мне, что именно вам мешает с ними разобраться (из объективных причин, которые можно объяснить и помочь вам) я приостановлю свои комментарии на ваши задачи касательно проблем с использованием данных конструкций.
Название: Re:Вывод нескольких элементов справочника через запятую и в конце с точкой
Отправлено: Axiomateria от 18 Октября 2013, 12:40:00
если вы пишите шаблон с таким match
<xsl:template match="property[@name='nearest_metro_station_spb']"  mode="metro_station_list"> 

то внутри этого шаблона вы работает от этого match, то есть от property и для получения доступа к узлу value вам надо писать не
.//property[@name = 'nearest_metro_station_spb']/value , а просто value    

Спасибо, admin.
Действительно ошибочка моя была в одном простом моменте с item в шаблоне - это моя торопливость и невнимательность в совокупе тому причина.

Теперь всё стало на свои места в таком работающем виде:
	 <xsl:template match="item" mode="metro_station_list">
<xsl:text>Ближайшая ст. Метро:</xsl:text>  
<span><xsl:value-of select="@name" /></span>
<xsl:text>, </xsl:text>
</xsl:template>
<xsl:template match="item[position() = last()]" mode="metro_station_list">
<span><xsl:value-of select="@name" /></span>
<xsl:text>.</xsl:text>
</xsl:template>
Название: Re:Вывод нескольких элементов справочника через запятую и в конце с точкой
Отправлено: Axiomateria от 21 Октября 2013, 12:32:48
И вот наконец-то мне удалось вывести на 100% правильный результат в котором заголовок перечисления станций метро "Ближайшая ст. Метро" не выводиться если не выбрано ни одно значение из списка множественного выбора.
Однако мне интересно, нельзя ли оптимизировать код приведённый ниже, а то он трёхэтажный получился в итоге таком:
 
Вызов:
<xsl:template match="udata" mode="hotel-object-view">
<xsl:apply-templates select=".//property[@name = 'nearest_metro_station_spb']" mode="metro_station_list" />
</xsl:template>
Шаблон
     <xsl:template match="property" mode="metro_station_list">
         <xsl:text>Ближайшая ст. Метро:</xsl:text>
        <xsl:apply-templates select="value" mode="metro_station_list"/>    
     </xsl:template>
     <xsl:template match="property[value = '']" mode="metro_station_list"></xsl:template>  
     <xsl:template match="value" mode="metro_station_list">
        <xsl:apply-templates select="item" mode="metro_station_list"/>  
     </xsl:template>    
     <xsl:template match="item" mode="metro_station_list">
   <xsl:value-of select="@name"/>
        <xsl:if test="not(position()=last())">, </xsl:if>
   <xsl:if test="(position()=last())">.</xsl:if>
     </xsl:template>