簡體   English   中英

XSL 風格:使用<xsl:for-each select>或者<xsl:template match>或 XSLT 中的其他解決方案?</xsl:template></xsl:for-each>

[英]XSL style: using <xsl:for-each select> or <xsl:template match> or other solutions in XSLT?

我正在學習使用 XSL 將 XML 解析為 HTML/XHTML。

XLST <xsl:for-each>元素是允許循環的語言的核心元素。 然而,這里和其他地方的帖子建議使用這對初學者來說很常見(我就是。)而且風格很差。

我的問題是: <xsl:for-each>循環有哪些更好的(如更高效/優雅/更好的風格)選項,為什么?

在下面的示例中,我使用嵌套<xsl:for-each><xsl:choose>元素通過條件<xsl:when>測試循環遍歷所需的節點。 這工作正常並選擇我需要的節點,但感覺相當笨重......

您的智慧和見解將不勝感激!

我的示例 XML 是由斯坦福 HIVdb 數據庫查詢生成的報告: https://hivdb.stanford.edu/hivdb/by-sequences/

XSD 架構在這里: https://hivdb.stanford.edu/DR/schema/sierra.xsd

我的示例 XML 報告在這里: https://github.com/delfair/xml_examples/blob/main/Resistance_1636677016671.Z0F635D0E0F3874CFF8AZ58E

我的示例 XSLT:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">

<html>
<head>
    <title>Example Report</title>
</head>
<body>

<h3>Significant mutations</h3>

<xsl:for-each select=".//geneData">
    <xsl:choose>
        <xsl:when test="gene='HIV1PR'">
        Protease inhibitor mutations<br/><br/>
        </xsl:when>
        <xsl:when test="gene='HIV1RT'">
        Reverse transcriptase inhibitor mutations<br/><br/>
        </xsl:when>
        <xsl:when test="gene='HIV1IN'">
        Integrase inhibitor mutations<br/><br/>
        </xsl:when>
    </xsl:choose>
<table>
<xsl:for-each select=".//mutation">
    <xsl:choose>
        <xsl:when test="classification='PI_MAJOR' or classification='PI_MINOR' or classification='NRTI' or classification='NNRTI' or classification='INI_MAJOR' or classification='INI_MINOR'">
        <tr>
        <td>Class</td>
        <td>Mutation</td>
        </tr>
        <tr>
            <td><xsl:value-of select="classification"/></td>
            <td><xsl:value-of select="mutationString"/></td>
        </tr>
        </xsl:when>
    </xsl:choose>
</xsl:for-each>
</table><br/>
</xsl:for-each>

</body>
</html>

</xsl:template>
</xsl:stylesheet>

結果 HTML:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Example Report</title>
</head>
<body>
<h3>Significant mutations</h3>
Protease inhibitor mutations<br><br><table></table>
<br>
Reverse transcriptase inhibitor mutations<br><br><table>
<tr>
<td>Class</td>
<td>Mutation</td>
</tr>
<tr>
<td>NNRTI</td>
<td>K103N</td>
</tr>
</table>
<br>
Integrase inhibitor mutations<br><br><table></table>
<br>
</body>
</html>

我猜您所說的“高級樣式”是指使用模板(進行模式匹配)而不是xsl:for-each “循環”。

您的代碼的核心功能可以轉換如下:

...
      <h3>Significant mutations</h3>

      <xsl:apply-templates select=".//geneData" />
      <table>
        <xsl:apply-templates select=".//mutation" />
      </table><br/>
    </body>
  </html>
</xsl:template>
<!-- End of main template matching "/" -->

<xsl:template match="geneData[gene='HIV1PR']">Protease inhibitor mutations<br/><br/></xsl:template>
<xsl:template match="geneData[gene='HIV1RT']">Reverse transcriptase inhibitor mutations<br/><br/></xsl:template>
<xsl:template match="geneData[gene='HIV1IN']">Integrase inhibitor mutations<br/><br/></xsl:template>

<xsl:template match="mutation[classification='PI_MAJOR' or classification='PI_MINOR' or classification='NRTI' or classification='NNRTI' or classification='INI_MAJOR' or classification='INI_MINOR']">
        <tr>
            <td>Class</td>
            <td>Mutation</td>
        </tr>
        <tr>
            <td><xsl:value-of select="classification"/></td>
            <td><xsl:value-of select="mutationString"/></td>
        </tr>
</xsl:template>

</xsl:stylesheet>

在上面的代碼中,兩組節點( .//geneData.//mutation )都被傳遞給xsl:apply-templates ,后者將結果節點傳遞給所有模板。 那些匹配的人將被處決。 因此,簡短的xsl:template帶有謂詞( match="..."[...]部分),它們替換了代碼的xsl:when

這應該是 XSLT 開發的“標准”方法。 在實踐中,在某些用例中, xsl:for-each可能更適合代碼清晰,但通常這兩種方法是可以互換的。

首先, xsl:for-each不用於“循環”。 它沒有退出條件,也無法將一次迭代的結果傳遞給另一次迭代。

接下來,使用xsl:for-each不僅限於初學者,也不是“糟糕的風格”——盡管您可能在這里或其他任何地方讀過。

xsl:for-each指令只不過是在特殊情況下使用的快捷方式。 一般方法分為兩個階段:

  • 首先,您 select 一組節點並告訴處理器將模板應用於它們;

  • 接下來,處理器找到與所選節點集中的每個節點最匹配的模板並應用它。

如果 (1) 您想對所選集中的所有節點應用統一處理,並且 (2) 不需要遞歸應用模板或重新使用它,您可以簡單地告訴處理器:獲取這些節點並將此模板應用於他們。

這正是xsl:for-each指令的作用。 它有一個select屬性到 select 要處理的節點,其內容是要應用於所選節點集的模板 不多也不少。 這里沒有范式轉變。 沒有“推式”與“拉式”。 沒有善與惡。

xsl:for-each是樣式表作者工具箱中的唯一工具時,就會出現唯一的問題。 正如我所說,它是一種可以在特殊情況下使用的捷徑。 當這些情況不適用時,使用它會導致代碼非常糟糕。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM