[英]Understanding “exsl:node-set” for Multiple operations on input xml
我試圖理解“ exsl:node-set”的概念及其用法,該概念使您能夠處理XML中已處理/生成的元素。 誰能幫忙
我從開發XSL代碼開始,該代碼可以按順序執行以下活動:
示例:在下面的示例輸入文件中,每個記錄
輸入XML
<?xml version="1.0" encoding="UTF-8"?>
<top>
<Level1>
<Results>
<a>no</a>
<b>10</b>
<b_nom>1.66</b_nom>
<c>12</c>
<d>9</d>
</Results>
</Level1>
<Level1>
<Results>
<a>no</a>
<b>8</b>
<b_nom>1.33</b_nom>
<c>50</c>
<d>12</d>
</Results>
<Level1>
</Level1>
<Results>
<a>no</a>
<b>6</b>
<b_nom>1</b_nom>
<c>55</c>
<d>56</d>
</Results>
<Level1>
</Level1>
<Results>
<a>yes</a>
<b>23</b>
<b_nom>1</b_nom>
<c>32</c>
<d>34</d>
</Results>
</Level1>
</top>
代碼: 提供此代碼是為了回答先前的問題 ,在該問題中,示例XML在樹中只有兩個級別,即。 <top><Results>
為此,它工作得很好,但是對於上述XML輸入,我丟失了<Level1>
數據。 我不理解該代碼並進行必要的更正。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common" exclude-result-prefixes="exsl">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="step1-result-fragment">
<xsl:apply-templates select="top" mode="step1"/>
</xsl:variable>
<xsl:variable name="step1-result" select="exsl:node-set($step1-result-fragment)"/>
<xsl:template match="@* | node()" name="identity">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@* | node()" mode="step1" name="step1-identity">
<xsl:copy>
<xsl:apply-templates select="@* | node()" mode="step1"/>
</xsl:copy>
</xsl:template>
<xsl:template match="c" mode="step1">
<avg><xsl:value-of select="(. + ../d) div 2"/></avg>
<xsl:call-template name="step1-identity"/>
</xsl:template>
<xsl:template match="/*">
<xsl:copy>
<xsl:variable name="min-avg">
<xsl:for-each select="$step1-result/top//Results/avg">
<xsl:sort select="." data-type="number"/>
<xsl:if test="position() = 1">
<xsl:value-of select="."/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:apply-templates select="$step1-result/top//Results">
<xsl:with-param name="min-avg" select="$min-avg"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="Results">
<xsl:param name="min-avg"/>
<xsl:copy>
<xsl:apply-templates select="@* | node()">
<xsl:with-param name="min-avg" select="$min-avg"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="avg">
<xsl:param name="min-avg"/>
<xsl:call-template name="identity"/>
<avg_nom><xsl:value-of select=". div $min-avg"/></avg_nom>
</xsl:template>
</xsl:stylesheet>
我需要的不僅是對上面的代碼進行更正以獲得正確的輸出,而且還需要進一步理解代碼。 為此,我想在上面的示例中添加一個附加步驟
因此,最終輸出應如下所示
<?xml version="1.0"?>
<top>
<Level1>
<Results>
<a>no</a>
<b>10</b>
<b_nom>1.66</b_nom>
<avg>10.5</avg>
<avg_nom>1</avg_nom>
<final>5.5</final>
<c>12</c>
<d>9</d>
</Results>
</Level1>
<Level1>
<Results>
<a>no</a>
<b>8</b>
<b_nom>1.33</b_nom>
<avg>31</avg>
<avg_nom>2.95238095238095</avg_nom>
<final>2.14</final>
<c>50</c>
<d>12</d>
</Results>
</Level1>
<Level1>
<Results>
<a>no</a>
<b>6</b>
<b_nom>1</b_nom>
<avg>55.5</avg>
<avg_nom>5.28571428571429</avg_nom>
<final>3.14</final>
<c>55</c>
<d>56</d>
</Results>
</Level1>
<Level1>
<Results>
<a>yes</a>
<b>23</b>
<b_nom>1</b_nom>
<avg>33</avg>
<avg_nom>3.14285714285714</avg_nom>
<final>2.07</final>
<c>32</c>
<d>34</d>
</Results>
</Level1>
</top>
在XSLT 2.0中,可以創建一個值為樹的變量:
<xsl:variable name="temp">
<root>
<xsl:call-template name="do-something"/>
</root>
</xsl:variable>
然后您可以使用XSLT的全部功能來處理此樹
<xsl:apply-templates select="$temp" mode="postprocess"/>
這允許樣式表在多個階段中操作:您可以創建一個中間結果,然后對其進行后處理:您可以根據需要在多個階段中執行轉換。
在XSLT 1.0中,由於在規范開發的后期出現嚴重的設計錯誤,因此不允許這樣做。 通過使$temp
成為“結果樹片段”並禁止對結果樹片段執行xsl:apply-templates之類的操作來實施此限制。
該錯誤在XSLT 1.0發布后很快就意識到了,處理器供應商通過引入擴展功能exslt:node-set()繞開了它,而沒有引入與規范不符的地方。 這可以讓你寫
<xsl:apply-templates select="exslt:node-set($temp)" mode="postprocess"/>
從概念上講,exslt:node-set()將結果樹片段(不允許處理xsl:apply-templates)轉換為單例節點集(是)。 可能在大多數實現中,它都是無操作的。
我希望這可以幫助您了解樣式表在做什么。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.