我对XSLT比较陌生,但我正在努力学习它以为客户提供解决方案。虽然最终目的是为Filemaker Pro编写一个XSLT,但我想首先得到一个HTML。
我收到一个生成的XML文件,其中包含旅游预订信息。它包含的信息以及订单数量也各不相同。
需要XSLT以更易于呈现的表格形式呈现所有XML信息。
当我输入条件语句时,我的问题就开始了。在示例中,如果BSServType ='TUTU'的值,该表应该反映一些信息,否则它应该查找值'SOHO',如果不是'SOVI'。
这个特殊的标签本身就是DetSeg的孩子。有几个DetSeg标签。不幸的是,信息可能在任何1个标签中,因此XSLT应该能够查看正确的标签,然后选择其中一个值。我无法这样做。
第二个问题是下面的语句:当值为'TUTU'时,选择'BSServDest'似乎工作正常,因为它是'BSServType'的兄弟,但'BSServQuota'不是兄弟,而是''侄子,如果我可以这么说的话。这也是一个问题,因为我无法选择它们
我希望我在解释中已经足够清楚了。已粘贴XML和XSLT。我试过看一下网站,看看问题是否已经呈现,但是没有找到任何东西可以完全帮助我。我希望这个问题可以解决,因为还有几个条件语句,我将不得不按照相同的逻辑编写。
我有另一个疑问:是否可以适应我后来为Filemaker Pro编写的XSLT?
提前感谢所有人。
XML代码:
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="order.xsl" type="text/xsl" ?>
<AllBookingFnp>
<BookingFnp>
<BookSegServ>
<BookSeg>
<DetSeg>
<BSDataIni>2011-06-25</BSDataIni>
<BSDataFin>2011-07-02</BSDataFin>
<BSCodTGeogr>LOC</BSCodTGeogr>
<BSCodCGeogr>ATH</BSCodCGeogr>
<BSDesGeogr><![CDATA[ATENE]]></BSDesGeogr>
<BSServType>TUTU</BSServType>
<BSServCod>GREMETEORE</BSServCod>
<BSServDes><![CDATA[TOUR GRECIA CLASSICA E METEORE]]></BSServDes>
<BSServTimeIni></BSServTimeIni>
<BSServDest>GRECIT</BSServDest>
</DetSeg>
<BSSservSpec>
<BSservQtall>1</BSservQtall>
<BSServQuota>DBLCDM</BSServQuota>
<BSServCodSist>DBL</BSServCodSist>
<BSServCodTrat>CDM</BSServCodTrat>
<BSServSist><![CDATA[DOPPIA]]></BSServSist>
<BSservTrat><![CDATA[COME DA PROGRAMMA]]></BSservTrat>
</BSSservSpec>
<BSFornText>SERVIZIO FORNITO DA:</BSFornText>
<BSFornDescr><![CDATA[PANHELLAS]]></BSFornDescr>
<BSFornInd><![CDATA[EL.VENIZELOU 161 N.ERYTHREA 14671]]></BSFornInd>
<BSFornLoc><![CDATA[ATHENS]]></BSFornLoc>
<BSFornTel>0030 210 8003073</BSFornTel>
<BSFornFax>Fax 8003030</BSFornFax>
</BookSeg>
<BookSeg>
<DetSeg>
<BSDataIni>2011-07-02</BSDataIni>
<BSDataFin>2011-07-09</BSDataFin>
<BSCodTGeogr>LOC</BSCodTGeogr>
<BSCodCGeogr>HYDV</BSCodCGeogr>
<BSDesGeogr><![CDATA[HYDRA - GRECIA]]></BSDesGeogr>
<BSServType>SOVI</BSServType>
<BSServCod>GREHYDRABEAC</BSServCod>
<BSServDes><![CDATA[HYDRA BEACH - VILLAGGIO VALTUR]]></BSServDes>
<BSServTimeIni></BSServTimeIni>
<BSServDest>GRECIA</BSServDest>
</DetSeg>
<BSSservSpec>
<BSservQtall>1</BSservQtall>
<BSServQuota>DBOCLAFV</BSServQuota>
<BSServCodSist>DBOCLA</BSServCodSist>
<BSServCodTrat>FV</BSServCodTrat>
<BSServSist><![CDATA[DOPPIA+letto uso doppia CLASSIC]]></BSServSist>
<BSservTrat><![CDATA[]]></BSservTrat>
</BSSservSpec>
<BSAnagRis>
<BSAnagDesRis><![CDATA[]]></BSAnagDesRis>
<BSAnagIndRis><![CDATA[A.E. PLEPI-THERMISIA]]></BSAnagIndRis>
<BSAnagLocRis><![CDATA[ERMIONI]]></BSAnagLocRis>
<BSAnagTelRis></BSAnagTelRis>
<BSAnagFaxRis></BSAnagFaxRis>
</BSAnagRis>
<BSServNoteDet><![CDATA[NOTA BENE: ALL'ARRIVO GLI OSPITI CHE NON UTILIZZANO I TRASPORTI VALTUR]]></BSServNoteDet>
<BSServNoteDet><![CDATA[SONO ATTESI DOPO LE ORE 16:00. IL GIORNO DELLA VOSTRA PARTENZA VI]]></BSServNoteDet>
<BSServNoteDet><![CDATA[INVITIAMO A LIBERARE LE STANZE PRIMA DELLE ORE 10:00.]]></BSServNoteDet>
<BSServNoteDet><![CDATA[**********************************************************************]]></BSServNoteDet>
<BSFornInd><![CDATA[]]></BSFornInd>
<BSFornLoc><![CDATA[]]></BSFornLoc>
<BSFornTel></BSFornTel>
<BSFornFax></BSFornFax>
</BookSeg>
</BookSegServ>
</BookingFnp>
<BookingFnp>
<BookSegServ>
<BookSeg>
<DetSeg>
<BSDataIni>2011-06-25</BSDataIni>
<BSDataFin>2011-06-25</BSDataFin>
<BSServType>TFTI</BSServType>
<BSServCod>NYCAPTHTL-I</BSServCod>
<BSServDes><![CDATA[TRANSFER APT NEW YORK-HOTEL]]></BSServDes>
<BSServTimeIni></BSServTimeIni>
<BSServDest>USA</BSServDest>
</DetSeg>
<BSSservSpec>
<BSservQtall>2</BSservQtall>
<BSServQuota></BSServQuota>
<BSServCodSist></BSServCodSist>
<BSServCodTrat></BSServCodTrat>
<BSServSist><![CDATA[]]></BSServSist>
<BSservTrat><![CDATA[]]></BSservTrat>
</BSSservSpec>
<BSServFrom><![CDATA[AZ 642 FCO-EWR 25/06/11 13:45]]></BSServFrom>
<BSServTo><![CDATA[RADISSON LEXINGTON HOTEL]]></BSServTo>
<BSFornText>SERVIZIO FORNITO DA:</BSFornText>
<BSFornDescr><![CDATA[TEAM AMERICA INC]]></BSFornDescr>
<BSFornInd><![CDATA[125 PARK AVENUE, 2ND FLOOR]]></BSFornInd>
<BSFornLoc><![CDATA[NEW YORK]]></BSFornLoc>
<BSFornTel>001 212 6977165</BSFornTel>
<BSFornFax>Fax 7182471706</BSFornFax>
</BookSeg>
<BookSeg>
<DetSeg>
<BSDataIni>2011-06-25</BSDataIni>
<BSDataFin>2011-07-02</BSDataFin>
<BSServType>SOHO</BSServType>
<BSServCod>NYCLEXINGTON</BSServCod>
<BSServDes><![CDATA[RADISSON LEXINGTON HOTEL]]></BSServDes>
<BSServTimeIni></BSServTimeIni>
<BSServDest>USA</BSServDest>
</DetSeg>
<BSSservSpec>
<BSservQtall>1</BSservQtall>
<BSServQuota>DBL</BSServQuota>
<BSServCodSist>DBL</BSServCodSist>
<BSServCodTrat></BSServCodTrat>
<BSServSist><![CDATA[DOPPIA]]></BSServSist>
<BSservTrat><![CDATA[]]></BSservTrat>
</BSSservSpec>
<BSAnagRis>
<BSAnagDesRis><![CDATA[]]></BSAnagDesRis>
<BSAnagIndRis><![CDATA[]]></BSAnagIndRis>
<BSAnagLocRis><![CDATA[NEW YORK]]></BSAnagLocRis>
<BSAnagTelRis></BSAnagTelRis>
<BSAnagFaxRis></BSAnagFaxRis>
</BSAnagRis>
<BSFornInd><![CDATA[]]></BSFornInd>
<BSFornLoc><![CDATA[]]></BSFornLoc>
<BSFornTel></BSFornTel>
<BSFornFax></BSFornFax>
</BookSeg>
<BookSeg>
<DetSeg>
<BSDataIni>2011-06-25</BSDataIni>
<BSDataFin>2011-06-25</BSDataFin>
<BSServType>TFTI</BSServType>
<BSServCod>NYCAPTHTL-O</BSServCod>
<BSServDes><![CDATA[TRANSFER HOTEL-APT NEW YORK]]></BSServDes>
<BSServTimeIni></BSServTimeIni>
<BSServDest>USA</BSServDest>
</DetSeg>
<BSSservSpec>
<BSservQtall>2</BSservQtall>
<BSServQuota></BSServQuota>
<BSServCodSist></BSServCodSist>
<BSServCodTrat></BSServCodTrat>
<BSServSist><![CDATA[]]></BSServSist>
<BSservTrat><![CDATA[]]></BSservTrat>
</BSSservSpec>
<BSServFrom><![CDATA[AZ 642 FCO-EWR 25/06/11 13:45]]></BSServFrom>
<BSServTo><![CDATA[RADISSON LEXINGTON HOTEL]]></BSServTo>
<BSFornText>SERVIZIO FORNITO DA:</BSFornText>
<BSFornDescr><![CDATA[TEAM AMERICA INC]]></BSFornDescr>
<BSFornInd><![CDATA[125 PARK AVENUE, 2ND FLOOR]]></BSFornInd>
<BSFornLoc><![CDATA[NEW YORK]]></BSFornLoc>
<BSFornTel>001 212 6977165</BSFornTel>
<BSFornFax>Fax 7182471706</BSFornFax>
</BookSeg>
</BookSegServ>
</BookingFnp>
</AllBookingFnp>
XSLT:`
<?xml version='1.0'?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>Liste des commandes</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Destination</th>
<th>BSServQuota</th>
</tr>
<xsl:for-each select="AllBookingFnp/BookingFnp">
<tr>
<xsl:choose>
<xsl:when test="BookSegServ/BookSeg/DetSeg/BSServType='TUTU'">
<td><xsl:value-of select="BookSegServ/BookSeg/DetSeg/BSServDest" /></td>
<td><xsl:value-of select="BookSegServ/BookSeg/BSSservSpec/BSServQuota" /></td>
</xsl:when>
<xsl:when test="BookSegServ/BookSeg/DetSeg/BSServType='SOHO'">
<td><xsl:value-of select="BookSegServ/BookSeg/DetSeg/BSServDest" /></td>
<td><xsl:value-of select="BookSegServ/BookSeg/BSSservSpec/BSServQuota" /></td>
</xsl:when>
<xsl:when test="BookSegServ/BookSeg/DetSeg/BSServType='SOVI'">
<td><xsl:value-of select="BookSegServ/BookSeg/DetSeg/BSServDest" /></td>
<td><xsl:value-of select="BookSegServ/BookSeg/BSSservSpec/BSServQuota" /></td>
</xsl:when>
</xsl:choose>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
我得到的结果如下表所示:
目的地: GRECIT USA
BSServQuota: DBLCDM -
从XML文件中,信息来自第一个<DetSeg>
的{{1}},因为它可以看到信息TUTU存在但在第二行,它无法这样做信息TUTU / SOHO或SOVI不在第一个<BookingFnp>
中,而在第二个<DetSeg>
中。它应该在第二个<DetSeg>
中查看并验证'SOHO',从而从<BSServQuota>
选择'DBL'
我希望看看所有三个<DetSeg>
并查找值'TUTU',如果存在,请查找我想要的信息,否则查找值'SOHO',否则'SOVI'。
感谢。
答案 0 :(得分:2)
你陷入了陷阱:你会看到像for-each这样的结构,并选择其他语言看起来很熟悉,而你本能地使用它们而不是其他不那么熟悉的结构。因此,您不是以“XSLT方式”编写代码。 XSLT方式是使用模板规则:模板匹配输入中出现的特定模式。这有时被称为“推送处理”,与“拉动处理”不同。
所以这种代码:
<xsl:choose>
<xsl:when test="BookSegServ/BookSeg/DetSeg/BSServType='TUTU'">
<td><xsl:value-of select="BookSegServ/BookSeg/DetSeg/BSServDest" /></td>
<td><xsl:value-of select="BookSegServ/BookSeg/BSSservSpec/BSServQuota" /></td>
应该写成这样:
<xsl:apply-templates select="BookSegServ/BookSeg"/>
<xsl:template match="BookSeg[DetSeg/BSServType='TUTU']">
<td><xsl:value-of select="DetSeg/BSServDest"/></td>
<td><xsl:value-of select="BSSservSpec/BSServQuota" /></td>
</xsl:template>
使用与BSServType的其他值匹配的其他模板规则。
(我只想在这里指出你正确的方向,而不是提供工作代码)。
答案 1 :(得分:2)
我设法得到答案并让我的XSLT正常工作。我得到了专家的帮助,但我想我会分享答案: 迈克尔凯让我走上了正确的轨道,但我自己无法做到,但无论如何它在这里:
<?xml version='1.0'?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/AllBookingFnp">
<html>
<body>
<h2>Liste des commandes</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Destination</th>
<th>BSServQuota</th>
</tr>
<xsl:apply-templates select="BookingFnp"></xsl:apply-templates>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="BookingFnp">
<xsl:choose>
<xsl:when test="BookSegServ/BookSeg/DetSeg/BSServType='TUTU'">
<xsl:apply-templates select="BookSegServ/BookSeg/DetSeg[BSServType='TUTU']"/>
</xsl:when>
<xsl:when test="BookSegServ/BookSeg/DetSeg/BSServType='SOHO'">
<xsl:apply-templates select="BookSegServ/BookSeg/DetSeg[BSServType='SOHO']"/>
</xsl:when>
<xsl:when test="BookSegServ/BookSeg/DetSeg/BSServType='SOVI'">
<xsl:apply-templates select="BookSegServ/BookSeg/DetSeg[BSServType='SOVI']"/>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template match="DetSeg">
<tr>
<td><xsl:value-of select="BSServDest" /></td>
<td><xsl:value-of select="parent::BookSeg/BSSservSpec/BSServQuota" /></td>
</tr>
</xsl:template>
</xsl:stylesheet>
感谢所有试图帮助我的人。
答案 2 :(得分:0)
这里有一个完全模板驱动的示例解决方案(没有循环,没有选择):
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" omit-xml-declaration="yes" />
<xsl:template match="/AllBookingFnp">
<html>
<body>
<h2>Liste des commandes</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Destination</th>
<th>BSServQuota</th>
</tr>
<xsl:apply-templates select="BookingFnp"/>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="BookingFnp">
<tr>
<xsl:apply-templates select="BookSegServ/BookSeg/DetSeg"/>
</tr>
</xsl:template>
<xsl:template match="DetSeg[BSServType='TUTU']">
<xsl:apply-templates select="BSServDest"/>
</xsl:template>
<xsl:template match="DetSeg[BSServType='SOHO' and
not(parent::BookSeg/
preceding-sibling::BookSeg[1]/
DetSeg[BSServType='TUTU'])]">
<xsl:apply-templates select="BSServDest"/>
</xsl:template>
<xsl:template match="DetSeg[BSServType='SOVI' and
not(parent::BookSeg/
preceding-sibling::BookSeg/
DetSeg[BSServType='SOHO'] or
parent::BookSeg/
preceding-sibling::BookSeg/
DetSeg[BSServType='TUTU']
)]">
<xsl:apply-templates select="BSServDest"/>
</xsl:template>
<xsl:template match="BSServDest">
<td><xsl:value-of select="." /></td>
<td><xsl:value-of select="
parent::DetSeg/
following-sibling::BSSservSpec/
BSServQuota" /></td>
</xsl:template>
<xsl:template match="*"/>
</xsl:stylesheet>