我正在使用营销平台来展示一个人为航班订购的行李。一名乘客可以将多个细分作为整体旅程的一部分。因此,如果我们有如下所示的记录(每个记录都有一个唯一的值,因为它在被拉出之前都被插入到数据库中,这里的xml是我正在使用的模型)。
编辑8/9 - 下面的实际XML和修订的XSLT。另外,如果您在Bag部分查看此链接(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>
答案 0 :(得分:1)
在没有看到预期HTML的样本的情况下提供精确答案并且因为XSLT中的元素名称似乎与输入XML样本不匹配,这有点棘手。但是,您需要阅读和使用的技术是Muenchian Grouping。这是在XSLT 1.0中对元素进行分组的最有效方法。
在您的情况下,您希望获得乘客的独特旅程,然后获得每个旅程的第一段。您可以通过定义一个键来 journeynumber
来查找 passengersegment 元素。<xsl:key name="journey" match="passengersegment" use="journeynumber"/>
然后,要获得不同的旅程编号,您需要查看所有 passengersegment ,但只选择键中首先出现的 journeynumber 值。
<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)" />
答案 1 :(得分:1)
假设输出的carryonbagcount应该是每条腿的最大值,这里只是对Tim回答的一个小调整。
此输入文档......
<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>
到目前为止,OP已经改变了问题和样本数据,这确实是一个新问题。假设@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>