XSL / Сортировка значений дополнительных свойств

Заметка создана: 10 марта 2025 г.

Значения дополнительных свойств выбираются из нескольких таблиц и не имеют порядка сортировки, в отличии от самих дополнительных свойств. Если Вам необходимо выводить значения дополнительных свойств в порядке сортировки свойств, то в XSL-шаблоне необходимо вместо прямого применения шаблона к property_value применять шаблон к property, а из шаблона property применять шаблон к property_value с ограничением по property_id.

Вариант 1

<xsl:template match="shop_item">
    ...
        <xsl:apply-templates select="/shop/shop_item_properties//property">
                         <xsl:sort
                                                        select = "sorting"
                                                        data-type = "number"
                                                        order = "ascending"
                                        />
        </xsl:apply-templates>
    ...
 </xsl:template>

<xsl:template match="property">
       <xsl:variable name="property_id" select="@id" />
       <xsl:if test="/shop/shop_item/property_value[property_id = $property_id]/value/node() and /shop/shop_item/property_value[property_id = $property_id]/value != '' or /shop/shop_item/property_value[property_id = $property_id]/type != 2">
          <tr>
             <td><xsl:value-of disable-output-escaping="yes" select="name"/></td>
             <xsl:apply-templates select="/shop/shop_item/property_value[property_id = $property_id]" />
          </tr>
       </xsl:if>
 </xsl:template>

<xsl:template match="/shop/shop_item/property_value">
       <xsl:variable name="property_id" select="property_id" />
       <xsl:variable name="property" select="/shop/shop_item_properties//property[@id=$property_id]" />
       
       <td style="padding: 5px" bgcolor="#F5F5F5">
          <xsl:choose>
             <xsl:when test="$property/type = 7">
                <input type="checkbox" disabled="disabled">
                   <xsl:if test="value = 1">
                      <xsl:attribute name="checked">checked</xsl:attribute>
                   </xsl:if>
                </input>
             </xsl:when>
             <xsl:otherwise>
                <xsl:value-of disable-output-escaping="yes" select="value"/>
             </xsl:otherwise>
          </xsl:choose>
       </td>
 </xsl:template>

Рабочий вариант с сайта (вывод свойств разбит по директориям)

			<xsl:if test="count(property_value[property_dir_id=14])">
												<div class="property_list_title">Габариты и вес</div>
												<div class="propertys-property_list">
													<xsl:apply-templates select="/shop/shop_item_properties//property[property_dir_id=14]">
													    <xsl:sort
                                                        select = "sorting"
                                                        data-type = "number"
                                                        order = "ascending"
                                                    />
                                                    </xsl:apply-templates>
												</div>
			</xsl:if>
<xsl:template match="property">
           <xsl:variable name="property_id" select="@id" />
       <xsl:if test="/shop/shop_item/property_value[property_id = $property_id]/value/node() and /shop/shop_item/property_value[property_id = $property_id]/value != '' or /shop/shop_item/property_value[property_id = $property_id]/type != 2">

            <xsl:apply-templates select="/shop/shop_item/property_value[property_id = $property_id]" mode="property_list"/>
         
       </xsl:if>
 </xsl:template>
	<!-- Вывод строки со значением свойства -->
	<xsl:template match="property_value" mode="property_list">
			<xsl:f test="value/node() and value != '' or file/node() and file != ''">
					<div class="shop_property">
								<xsl:variable name="property_id" select="property_id" />
								<xsl:variable name="property" select="/shop/shop_item_properties//property[@id=$property_id]" />

								<span class="property-name">
									<xsl:value-of select="$property/name"/>
								</span>
								<span class="property-value"><xsl:choose>
										<xsl:when test="$property/type = 2">
											<a href="{../dir}{file}" target="_blank"><xsl:value-of select="file_name"/></a>
										</xsl:when>
										<xsl:when test="$property/type = 5">
											<a href="{informationsystem_item/url}"><xsl:value-of select="informationsystem_item/name"/></a>
										</xsl:when>
										<xsl:when test="$property/type = 7">
											<input type="checkbox" disabled="disabled">
												<xsl:if test="value = 1">
													<xsl:attribute name="checked">checked</xsl:attribute>
												</xsl:if>
											</input>
										</xsl:when>
										<xsl:when test="$property/type = 12">
											<a href="{shop_item/url}"><xsl:value-of select="shop_item/name"/></a>
										</xsl:when>
										<xsl:otherwise>
											<xsl:value-of disable-output-escaping="yes" select="value"/>
											<!-- Единица измерения свойства -->
											<xsl:if test="$property/shop_measure/node()">
												<xsl:text> </xsl:text><xsl:value-of select="$property/shop_measure/name"/>
											</xsl:if>
										</xsl:otherwise>
								</xsl:choose></span>
					</div>
			</xsl:if>
	</xsl:template>

Вариант 2


   <!-- Шаблон для товара -->
    <xsl:template match="shop_item">
       ...
          <xsl:variable name="myItem" select="." />
          
          <xsl:for-each select="/shop/shop_item_properties//property">
             <xsl:variable name="propertyId" select="@id" />
             <xsl:choose>
             <xsl:when test="count($myItem/property_value[property_id = $propertyId])">
                <xsl:apply-templates select="$myItem/property_value[property_id = $propertyId]"/>
             </xsl:when>
             <xsl:otherwise><td></td></xsl:otherwise>
             </xsl:choose>
          </xsl:for-each>
      ...
    </xsl:template>

Вариант 3

Используется при сортировке значений дополнительных свойств при выводе списка товаров. Хук вносится в код типовых динамических страниц и добавляет тег sort для значений доп. свойств (в примере для значений свойств целого и строчного типа).

Не путайте добавляемый тег sort с тегом sorting, в котором указывается внутренний порядок сортировки множественных значений свойства.
if (!$Shop_Controller_Show->item)
{
    class Property_Value_Observer
    {
        static public function onBeforeGetXml($object, $args)
        {
            $object->addXmlTag('sort', $object->Property->sorting);
        }
    }

    Core_Event::attach('property_value_string.onBeforeGetXml', array('Property_Value_Observer', 'onBeforeGetXml'));
    Core_Event::attach('property_value_int.onBeforeGetXml', array('Property_Value_Observer', 'onBeforeGetXml'));    
}

Вариант 4

Сортировка значений одного свойства в порядке добавления достигается указанием <xsl:sort select="@id" />, например:

<xsl:for-each select="property_value[tag_name='img'][file !='']">
    <xsl:sort select="@id" />
    <div class="item">
        <a href="{../dir}{file}" class="elevatezoom-gallery" data-image="{../dir}{file}" data-zoom-image="{../dir}{file}">
            <img class="img-responsive" height="150" width="100" src="{../dir}{file}"/>
        </a>
    </div>
</xsl:for-each>

XSL