簡體   English   中英

使用 xslt 3.0 在循環中查找

[英]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>

演示: https://xsltfiddle.liberty-development.net/3MXNWN3/1

暫無
暫無

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

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