2013-08-08 2 views
0

Я работаю с маркетинговой платформой, чтобы отобразить Сумки, которые человек заказал для полета. Один пассажир может иметь несколько сегментов как часть общего путешествия. Поэтому, если у нас есть записи, как показано ниже (каждая запись имеет уникальное значение, а также, так как это все вставлено в базу данных до вытаскивания, xml здесь представляет собой макет того, с чем работает im).Как использовать предыдущий брат для проверки предыдущего элемента xpath

Редактировать 8/9 - Фактический XML и пересмотренный XSLT ниже. Также, если вы посмотрите на эту ссылку (http://f.spiritairlines.com/ats/msg.aspx?sg1=2e4a4d00cb00be84c598b618d6556e3e) в разделе «Сумка». Я хочу, чтобы это выглядело как вторая строка (Педро Смит), а не первая строка (Сандра Смит). Кстати, это все тестовые данные, поэтому нет никаких проблем с конфиденциальностью, показывая вам, а также нет личной информации о них.

<bookingcontact_to_booking> 
    <passenger_to_bookings> 
     <passenger_to_booking> 
      <Prop pk_id="4147" entity_id="126" val="SMITH" type_id="20" prop_name="lastname" prop_id="10208"/> 
      <Prop pk_id="4147" entity_id="126" val="PEDRO" type_id="20" prop_name="firstname" prop_id="10206"/> 
      <passseg_to_passengers> 
       <passseg_to_passenger> 
        <Prop pk_id="9432" entity_id="122" val="2013-08-27 17:45:00.000" type_id="30" prop_name="arrivaltime" prop_id="10216"/> 
        <Prop pk_id="9432" entity_id="122" val="188" type_id="20" prop_name="flightnumber" prop_id="10217"/> 
        <Prop pk_id="9432" entity_id="122" val="5" type_id="10" prop_name="checkedbagcount" prop_id="10220"/> 
        <Prop pk_id="9432" entity_id="122" val="1" type_id="10" prop_name="carryonbagcount" prop_id="10221"/> 
        <Prop pk_id="9432" entity_id="122" val="1" type_id="10" prop_name="journeynumber" prop_id="10222"/> 
        <Prop pk_id="9432" entity_id="122" val="0" type_id="10" prop_name="segmentnumber" prop_id="10223"/> 
        <Prop pk_id="9432" entity_id="122" val="2013-08-27 08:12:00.000" type_id="30" prop_name="departuretime" prop_id="10296"/> 
        <Prop pk_id="9432" entity_id="122" val="Las Vegas, NV" type_id="20" prop_name="departureairport" prop_id="10297"/> 
        <Prop pk_id="9432" entity_id="122" val="New York, NY - LaGuardia " type_id="20" prop_name="arrivalairport" prop_id="10298"/> 
        <Prop pk_id="9432" entity_id="122" val="10B,20B" type_id="20" prop_name="seatassignment" prop_id="10299"/> 
       </passseg_to_passenger> 
       <passseg_to_passenger> 
        <Prop pk_id="9433" entity_id="122" val="10B,20B" type_id="20" prop_name="seatassignment" prop_id="10299"/> 
        <Prop pk_id="9433" entity_id="122" val="Fort Lauderdale, FL" type_id="20" prop_name="arrivalairport" prop_id="10298"/> 
        <Prop pk_id="9433" entity_id="122" val="New York, NY - LaGuardia " type_id="20" prop_name="departureairport" prop_id="10297"/> 
        <Prop pk_id="9433" entity_id="122" val="2013-08-27 19:45:00.000" type_id="30" prop_name="departuretime" prop_id="10296"/> 
        <Prop pk_id="9433" entity_id="122" val="1" type_id="10" prop_name="segmentnumber" prop_id="10223"/> 
        <Prop pk_id="9433" entity_id="122" val="1" type_id="10" prop_name="journeynumber" prop_id="10222"/> 
        <Prop pk_id="9433" entity_id="122" val="1" type_id="10" prop_name="carryonbagcount" prop_id="10221"/> 
        <Prop pk_id="9433" entity_id="122" val="5" type_id="10" prop_name="checkedbagcount" prop_id="10220"/> 
        <Prop pk_id="9433" entity_id="122" val="779" type_id="20" prop_name="flightnumber" prop_id="10217"/> 
        <Prop pk_id="9433" entity_id="122" val="2013-08-27 22:45:00.000" type_id="30" prop_name="arrivaltime" prop_id="10216"/> 
       </passseg_to_passenger> 
      </passseg_to_passengers> 
     </passenger_to_booking> 
    </passenger_to_bookings> 
</bookingcontact_to_booking> 

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

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="html" encoding="UTF-8" indent="yes" omit-xml-declaration="yes" /> 

    <xsl:key name="journey" match="passengersegment" use="Prop[@prop_name = 'journeynumber']/@val"/> 

    <xsl:template match="/"> 
     <xsl:for-each select="/Msg/Props/bookingcontact_to_booking/passenger_to_bookings/passenger_to_booking"> 
      <tr> 
       <td colspan="3"> 
        <table style="text-align: left; line-height: 18px; font-family: Arial, Helvetica, sans-serif; font-size: 12px; color:#333333;" 
        border="0" cellspacing="0" cellpadding="0" width="542" align="left"> 
         <tbody> 
          <tr> 
           <td height="22" width="200"> 
            <xsl:value-of select="Prop[@prop_name = 'firstname']/@val" /><xsl:text> </xsl:text><xsl:value-of select="Prop[@prop_name = 'lastname']/@val" /> 
           </td> 
           <xsl:apply-templates select="passengersegment[generate-id() = generate-id(key('journey', journeynumber)[1])]"/> 
          </tr> 
         </tbody> 
        </table> 
       </td> 
      </tr> 
     </xsl:for-each> 
    </xsl:template> 

    <xsl:template match="passengersegment"> 
     <td style="text-align: left;" width="100"> 
      <table style="text-align: left; line-height: 18px; font-family: Arial, Helvetica, sans-serif; font-size: 12px; color:#333333;" width="100"> 
       <tr> 
        <xsl:for-each select="passseg_to_passengers/passseg_to_passenger"> 
         <td width="50"> 
          <xsl:value-of select="Prop[@prop_name = 'carryonbagcount']/@val" /> 
         </td> 
        </xsl:for-each> 
       </tr> 
      </table>        
     </td> 
     <td style="text-align: left;" width="100"> 
      <table style="text-align: left; line-height: 18px; font-family: Arial, Helvetica, sans-serif; font-size: 12px; color:#333333;" width="100"> 
       <tr> 
        <xsl:for-each select="passseg_to_passengers/passseg_to_passenger"> 
         <td width="50"> 
          <xsl:value-of select="Prop[@prop_name = 'checkedbagcount']/@val" /> 
         </td> 
        </xsl:for-each> 
       </tr> 
      </table>        
     </td> 
    </xsl:template> 

</xsl:stylesheet> 
+2

Это очень помогло бы, если бы вы могли показать нам результат, который вы ожидаете. Кроме того, здесь используются XSLT 1.0 или XSLT 2.0, так как это очень похоже на проблему группировки, а группировка по-разному обрабатывается в версии 2.0. –

+0

@TimC Я использую XSLT 1.0, и вы можете увидеть версию того, над чем я сейчас работаю. http://f.spiritairlines.com/ats/msg.aspx?sg1=d2e6dc6863a21c17a7a6c4f861e16ae4. Если вы прокрутите страницу вниз до раздела «Сумки», раздел «Перенос и проверка мешков» должен иметь 1 пробел 1. – Src1988

+0

может быть не в тему, но надежды, на которые ссылаются данные, являются только тестовыми данными, в противном случае я не уверен, разрешено ли вам показывать это нам :) –

ответ

1

Это немного сложно дать точный ответ, не видя образец вашего ожидаемого HTML, а также потому, что имена элементов в вашем XSLT, похоже, не совпадают с образцом входного XML. Тем не менее, техника, которую вы должны читать и использовать здесь, - Muenchian Grouping. Это наиболее эффективный способ группировки элементов в XSLT 1.0.

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

<xsl:key name="journey" match="passengersegment" use="journeynumber"/> 

Затем, чтобы получить различные номера в пути, вы посмотрите на все passengersegment но выбрать только те, которые происходят первым в ключе для их данных номер путешествия значение.

<xsl:apply-templates 
    select="passengersegment 
      [generate-id() = generate-id(key('journey', journeynumber)[1])]"/> 

В шаблоне, который соответствует passengersegment вы можете затем вывести первый carryonbagcount и checkednbagcount для сегмента (первый в путешествии).

Попробуйте XSLT в качестве начала, и построить на этом:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 
    <xsl:key name="journey" match="passengersegment" use="journeynumber"/> 

    <xsl:template match="/passenger"> 
    <table border="1"> 
     <tr> 
     <th>Journey</th> 
     <th>Carry on</th> 
     <th>Checked</th> 
     </tr> 
     <xsl:apply-templates select="passengersegment[generate-id() = generate-id(key('journey', journeynumber)[1])]"/> 
    </table> 
    </xsl:template> 

    <xsl:template match="passengersegment"> 
    <tr> 
     <td> 
     <xsl:value-of select="journeynumber"/> 
     </td> 
     <td> 
     <xsl:value-of select="carryonbagcount"/> 
     </td> 
     <td> 
     <xsl:value-of select="checkedbagcount"/> 
     </td> 
    </tr> 
    </xsl:template> 
</xsl:stylesheet> 

Обратите внимание, что если хочет получить общее carryonbagcount для всех сегментов в пути, то в passengersegment вы могли бы сделать что-то вроде этого:

<xsl:value-of select="sum(key('journey', journeynumber)/carryonbagcount)" /> 
+0

Можете ли вы взглянуть на мои правки выше? Я включил настоящий пример xml и мой пересмотренный xsl и хороший пример того, что он искал? – Src1988

+0

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

1

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

Этот входной документ ...

<passenger> 
    <passengersegment> 
     <journeynumber>0</journeynumber> 
     <segmentnumber>0</segmentnumber> 
     <carryonbagcount>1</carryonbagcount> 
     <checkedbagcount>1</checkedbagcount> 
    </passengersegment> 
    <passengersegment> 
     <journeynumber>0</journeynumber> 
     <segmentnumber>1</segmentnumber> 
     <carryonbagcount>1</carryonbagcount> 
     <checkedbagcount>1</checkedbagcount> 
    </passengersegment> 
    <passengersegment> 
     <journeynumber>1</journeynumber> 
     <segmentnumber>0</segmentnumber> 
     <carryonbagcount>1</carryonbagcount> 
     <checkedbagcount>1</checkedbagcount> 
    </passengersegment> 
    <passengersegment> 
     <journeynumber>1</journeynumber> 
     <segmentnumber>1</segmentnumber> 
     <carryonbagcount>1</carryonbagcount> 
     <checkedbagcount>1</checkedbagcount> 
    </passengersegment> 

... когда XSLT 1.0 таблица стилей применяется к нему ...

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 
<xsl:output method="html" doctype-system="about:legacy-compat" encoding="UTF-8" indent="yes" /> 
<xsl:strip-space elements="*" /> 

<xsl:key name="kJourney" match="passengersegment" use="journeynumber" /> 

<xsl:template match="/*"> 
<table> 
<thead> 
    <tr> 
    <th><strong>Journey</strong></th> <th><strong>CARRY-ON</strong></th> <th><strong>CHECKED</strong></th> 
    </tr> 
</thead> 
<tbody> 
    <xsl:apply-templates select="passengersegment[generate-id() = 
                generate-id(key('kJourney',journeynumber)[1])]" 
         mode="group" /> 
</tbody> 
</table> 
</xsl:template> 

<xsl:template match="passengersegment" mode="group"> 
    <tr> 
    <td><xsl:value-of select="journeynumber" /></td> 

    <xsl:apply-templates select="." mode="max"> 
     <xsl:with-param name="col-name" select="'carryonbagcount'" /> 
    </xsl:apply-templates> 

    <xsl:apply-templates select="." mode="max"> 
     <xsl:with-param name="col-name" select="'checkedbagcount'" /> 
    </xsl:apply-templates> 
    </tr> 
</xsl:template> 

<xsl:template match="passengersegment" mode="max"> 
    <xsl:param name="col-name" /> 
    <xsl:for-each select="key('kJourney',journeynumber)/*[name()=$col-name]"> 
    <xsl:sort select="." data-type="number" order="descending" /> 
    <xsl:if test="position()=1"> 
     <td><xsl:value-of select="." /></td> 
    </xsl:if> 
    </xsl:for-each> 
</xsl:template> 

</xsl:stylesheet> 

... дает этот HTML выход ...

<!DOCTYPE html SYSTEM "about:legacy-compat"> 
<table> 
    <thead> 
    <tr> 
     <th><strong>Journey</strong></th> 
     <th><strong>CARRY-ON</strong></th> 
     <th><strong>CHECKED</strong></th> 
    </tr> 
    </thead> 
    <tbody> 
    <tr> 
     <td>0</td> 
     <td>1</td> 
     <td>1</td> 
    </tr> 
    <tr> 
     <td>1</td> 
     <td>1</td> 
     <td>1</td> 
    </tr> 
    </tbody> 
</table> 

Обновление

ОП изменил вопрос и образцы данных до сих пор, это действительно новый вопрос. Предполагая, что @entity_id однозначно идентифицирует пассажира. Если нет, OP должен правильно объяснить структуру входных данных и правила преобразования. Так вот это решение новый вопрос ..

Это XSLT 1.0 таблицы стилей ...

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 
<xsl:output method="html" doctype-system="about:legacy-compat" encoding="UTF-8" indent="yes" /> 
<xsl:strip-space elements="*" /> 

<xsl:key name="kJourney" match="passseg_to_passenger" 
    use="concat(../../Prop/@entity_id, '|', Prop[@prop_name='journeynumber']/@val)" /> 
    <!-- Assume that @entity_id is an identifier for the passenger. --> 

<xsl:template match="bookingcontact_to_booking"> 
<table> 
<thead> 
    <tr> 
    <th><strong>PASSENGER</strong></th> <th><strong>CARRY-ON</strong></th> <th><strong>CHECKED</strong></th> 
    </tr> 
</thead> 
<tbody> 
    <xsl:apply-templates select="passenger_to_bookings/passenger_to_booking" /> 
</tbody> 
</table> 
</xsl:template> 

<xsl:template match="passenger_to_booking"> 
    <xsl:variable name="passenger-id" select="(Prop/@entity_id)[1]" /> 
    <xsl:variable name="passenger-name" select=" 
    concat(Prop[@prop_name='firstname']/@val, ' ', Prop[@prop_name='lastname']/@val)" /> 
    <tr> 
    <xsl:apply-templates select="passseg_to_passengers/passseg_to_passenger 
     [generate-id() = generate-id(key('kJourney', 
      concat($passenger-id, '|', Prop[@prop_name='journeynumber']/@val))[1])]" 
    mode="group"> 
    <xsl:with-param name="passenger-id" select="$passenger-id" /> 
    <xsl:with-param name="passenger-name" select="$passenger-name" /> 
    </xsl:apply-templates> 
    </tr> 
</xsl:template> 

<xsl:template match="passseg_to_passenger" mode="group"> 
    <xsl:param name="passenger-id" /> 
    <xsl:param name="passenger-name" /> 
    <td><xsl:value-of select="$passenger-name" /></td> 

    <xsl:apply-templates select="." mode="max"> 
    <xsl:with-param name="passenger-id" select="$passenger-id" /> 
    <xsl:with-param name="col-name" select="'carryonbagcount'" /> 
    </xsl:apply-templates> 

    <xsl:apply-templates select="." mode="max"> 
    <xsl:with-param name="passenger-id" select="$passenger-id" /> 
    <xsl:with-param name="col-name" select="'checkedbagcount'" /> 
    </xsl:apply-templates> 
</xsl:template> 

<xsl:template match="passseg_to_passenger" mode="max"> 
    <xsl:param name="passenger-id" /> 
    <xsl:param name="col-name" /> 
    <xsl:for-each select="key('kJourney', 
     concat($passenger-id, '|', Prop[@prop_name='journeynumber']/@val) 
)/Prop[@prop_name=$col-name]/@val"> 
    <xsl:sort select="." data-type="number" order="descending" /> 
    <xsl:if test="position()=1"> 
     <td><xsl:value-of select="." /></td> 
    </xsl:if> 
    </xsl:for-each> 
</xsl:template> 

</xsl:stylesheet> 

... когда применяется к этому входному документу ...

<bookingcontact_to_booking> 
    <passenger_to_bookings> 
     <passenger_to_booking> 
      <Prop pk_id="4147" entity_id="126" val="SMITH" type_id="20" prop_name="lastname" prop_id="10208"/> 
      <Prop pk_id="4147" entity_id="126" val="PEDRO" type_id="20" prop_name="firstname" prop_id="10206"/> 
      <passseg_to_passengers> 
       <passseg_to_passenger> 
        <Prop pk_id="9432" entity_id="122" val="2013-08-27 17:45:00.000" type_id="30" prop_name="arrivaltime" prop_id="10216"/> 
        <Prop pk_id="9432" entity_id="122" val="188" type_id="20" prop_name="flightnumber" prop_id="10217"/> 
        <Prop pk_id="9432" entity_id="122" val="5" type_id="10" prop_name="checkedbagcount" prop_id="10220"/> 
        <Prop pk_id="9432" entity_id="122" val="1" type_id="10" prop_name="carryonbagcount" prop_id="10221"/> 
        <Prop pk_id="9432" entity_id="122" val="1" type_id="10" prop_name="journeynumber" prop_id="10222"/> 
        <Prop pk_id="9432" entity_id="122" val="0" type_id="10" prop_name="segmentnumber" prop_id="10223"/> 
        <Prop pk_id="9432" entity_id="122" val="2013-08-27 08:12:00.000" type_id="30" prop_name="departuretime" prop_id="10296"/> 
        <Prop pk_id="9432" entity_id="122" val="Las Vegas, NV" type_id="20" prop_name="departureairport" prop_id="10297"/> 
        <Prop pk_id="9432" entity_id="122" val="New York, NY - LaGuardia " type_id="20" prop_name="arrivalairport" prop_id="10298"/> 
        <Prop pk_id="9432" entity_id="122" val="10B,20B" type_id="20" prop_name="seatassignment" prop_id="10299"/> 
       </passseg_to_passenger> 
       <passseg_to_passenger> 
        <Prop pk_id="9433" entity_id="122" val="10B,20B" type_id="20" prop_name="seatassignment" prop_id="10299"/> 
        <Prop pk_id="9433" entity_id="122" val="Fort Lauderdale, FL" type_id="20" prop_name="arrivalairport" prop_id="10298"/> 
        <Prop pk_id="9433" entity_id="122" val="New York, NY - LaGuardia " type_id="20" prop_name="departureairport" prop_id="10297"/> 
        <Prop pk_id="9433" entity_id="122" val="2013-08-27 19:45:00.000" type_id="30" prop_name="departuretime" prop_id="10296"/> 
        <Prop pk_id="9433" entity_id="122" val="1" type_id="10" prop_name="segmentnumber" prop_id="10223"/> 
        <Prop pk_id="9433" entity_id="122" val="1" type_id="10" prop_name="journeynumber" prop_id="10222"/> 
        <Prop pk_id="9433" entity_id="122" val="1" type_id="10" prop_name="carryonbagcount" prop_id="10221"/> 
        <Prop pk_id="9433" entity_id="122" val="5" type_id="10" prop_name="checkedbagcount" prop_id="10220"/> 
        <Prop pk_id="9433" entity_id="122" val="779" type_id="20" prop_name="flightnumber" prop_id="10217"/> 
        <Prop pk_id="9433" entity_id="122" val="2013-08-27 22:45:00.000" type_id="30" prop_name="arrivaltime" prop_id="10216"/> 
       </passseg_to_passenger> 
      </passseg_to_passengers> 
     </passenger_to_booking> 
    </passenger_to_bookings> 
</bookingcontact_to_booking> 

... дает этот html выходной документ ...

<!DOCTYPE html SYSTEM "about:legacy-compat"> 
<table> 
    <thead> 
    <tr> 
     <th><strong>PASSENGER</strong></th> 
     <th><strong>CARRY-ON</strong></th> 
     <th><strong>CHECKED</strong></th> 
    </tr> 
    </thead> 
    <tbody> 
    <tr> 
     <td>PEDRO SMITH</td> 
     <td>1</td> 
     <td>5</td> 
    </tr> 
    </tbody> 
</table> 
+0

Можете ли вы взглянуть на мои изменения, чтобы увидеть реальный xml и html и пересмотренный xsl? – Src1988

+0

@ Src1988: обратитесь к обновлению –

Смежные вопросы