[英]Lookup in loop using xslt 3.0
我需要在遞歸循環中進行查找。 例如下面是一個 xml:
<?xml version="1.0" encoding="utf-8"?>
<AggregatedData>
<wd:Report_Data xmlns:wd="urn:com.workday/bsvc">
<wd:Report_Entry>
<wd:num>1</wd:num>
</wd:Report_Entry>
<wd:Report_Entry>
<wd:num>2</wd:num>
</wd:Report_Entry>
<wd:Report_Entry>
<wd:num>4</wd:num>
</wd:Report_Entry>
<wd:Report_Entry>
<wd:num>5</wd:num>
</wd:Report_Entry>
</wd:Report_Data>
<root>
<row>
<my_num>6</my_num> --->> Can be any number
</row>
</root>
</AggregatedData>
現在,如果可用,我需要在 Report_Data 中查找 my_num。 如果找到那么我需要從 my_num 中減去 1,然后再次查找直到“未找到”
例如,如果 my_num 為 6,我需要從 6(即 5)中減去 1,然后在 report_Data 中查找是否為 5。 如果找到,現在需要從 5 中減去 1(即 4),然后再次在 report_data 中查找 4。 繼續迭代這個循環,直到“未找到”
預期 output :未找到:3
下面是 xslt 到目前為止我能夠准備但面臨錯誤 xsl:template must be at top level,但我無法重新構建 xslt:
<xsl:template match="AggregatedData">
<FinalData>
<xsl:iterate select="*">
<xsl:param name="numMap" as="map(xs:integer,element(wd:Report_Entry))" select="map{}"/>
<xsl:choose>
<xsl:when test="self::wd:Report_Data">
<xsl:next-iteration>
<xsl:with-param name="numMap"
select="fold-left(
wd:Report_Entry/copy-of(),
map{},
function($map,$entry) {
let $key:=xs:integer($entry/wd:num) return
if ($key)
then map:put($map,$key,$entry)
else
$map})"
/>
</xsl:next-iteration>
</xsl:when>
<xsl:when test="self::root">
<xsl:for-each select="row/copy-of()">
<rows>
<xsl:copy-of select="*"/>
<splitExistFlag>
<xsl:choose>
<xsl:when test="exists($numMap(current()/xs:integer(my_num - 1))/wd:num)">
<xsl:value-of select="'found'"/>
------<< Need a recursive loop here after further subtracting 1 from my_num >>------
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="'Not found'"/>
</xsl:otherwise>
</xsl:choose>
</splitExistFlag>
</rows>
</xsl:for-each>
</xsl:when>
</xsl:choose>
</xsl:iterate>
</FinalData>
</xsl:template>
</xsl:樣式表>
請幫忙!
你想得太程序化了:
例如,如果 my_num 為 6,我需要從 6(即 5)中減去 1,然后在 report_Data 中查找是否為 5。 如果找到,現在需要從 5 中減去 1(即 4),然后再次在 report_data 中查找 4。 繼續迭代這個循環,直到“未找到”
嘗試用更聲明的方式表達它,你會發現編寫代碼更容易。
據我所知,您希望最高的 integer 低於my_num
中不存在的report_Data
。 也就是說,你想要
max((1 to my_num - 1)[not(. = //wd:num)])
或者如果數字更大,則可能要快一到兩微秒:
reverse(1 to my_num - 1)[not(. = //wd:num)][1]
我無法遵循您示例的邏輯。 以下是您可能能夠適應的簡單內容:
XSLT 2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:wd="urn:com.workday/bsvc"
exclude-result-prefixes="wd">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:key name="entry" match="wd:Report_Entry" use="wd:num" />
<xsl:template match="/AggregatedData">
<xsl:variable name="data" select="wd:Report_Data" />
<results>
<xsl:for-each select="root/row">
<row start="{my_num}">
<xsl:for-each select="reverse(1 to my_num)">
<result n="{.}">
<xsl:if test="not(key('entry', string(.), $data))">Not </xsl:if>
<xsl:text>found</xsl:text>
</result>
</xsl:for-each>
</row>
</xsl:for-each>
</results>
</xsl:template>
</xsl:stylesheet>
應用於您的(更新的)示例輸入,這將產生:
結果
<?xml version="1.0" encoding="UTF-8"?>
<results>
<row start="6">
<result n="6">Not found</result>
<result n="5">found</result>
<result n="4">found</result>
<result n="3">Not found</result>
<result n="2">found</result>
<result n="1">found</result>
</row>
</results>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.