XSLT中的条件语句,当必须从多个元素中选择标记时

|| 我对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美国 BSServQuota:DBLCDM- 从XML文件中,信息是从第一个“ 3”中的第一个“ 2”中获取的,因为它可以看到存在信息TUTU,但是在第二行中却无法这样做,因为信息TUTU / SOHO或SOVI不存在第一个
<DetSeg>
,但第二个。它应该在第二个
<DetSeg>
中查找并验证\'SOHO \',因此从
<BSServQuota>
中选择\'DBL \' 我希望它查看所有三个
<DetSeg>
并寻找值'TUTU \',如果存在,请输入我想要的信息,否则寻找值'SOHO \',否则寻找值'SOVI \'。 谢谢。     
已邀请:
        您在这里陷入了陷阱:您正在看到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的其他值匹配的其他模板规则。 (我只是在这里为您指明正确的方向,而不是提供有效的代码)。     
        我设法得到了答案并使我的XSLT工作。我得到了专家的帮助,但我想我会分享答案: 迈克尔·凯(Michael Kay)使我走上了正确的道路,但我无法独自做到,但无论如何,这里是:
<?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>
感谢所有试图帮助我的人。     
        在这里,您有一个示例解决方案,完全由模板驱动(无循环,无选择):
<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>
    

要回复问题请先登录注册