在 xsl 2.0 中从外部 for 循环访问值

问题描述 投票:0回答:1

我使用 xslt2.0 从另一个 xml 创建一个 xml。源xml如下-

<?xml version="1.0" encoding="UTF-8"?>
<Data>
    <set1>
        <line_data>
            <id>1</id>
            <some_data></some_data>
            <other_data></other_data>
            <allocation>
                <date>16-10-2023</date>
                <hours>1</hours>
            </allocation>
            <allocation>
                <date>23-10-2023</date>
                <hours>2</hours>
            </allocation>
            <allocation>
                <date>30-10-2023</date>
                <hours>3</hours>
            </allocation>
            <allocation>
                <date>06-11-2023</date>
                <hours>3</hours>
            </allocation>
        </line_data>
        <line_data>
           <id>2</id>
            <allocation>
                ....
            </allocation>
        </line_data>
        <line_data>
            
        </line_data>
    </set1>
    <entry>
        <id>1</id>
        <line_data>
            <week_hours>
                <start_date>23-10-2023</start_date>
                <time_hr>5</time_hr>
            </week_hours>
            <week_hours>
                <start_date>06-11-2023</start_date>
                <time_hr>10</time_hr>
            </week_hours>
        </line_data>
    </entry>
</Data>

我想从与 in 节点匹配的节点 中提取数据。对于每个标签,我需要检查 // 中是否存在具有相同日期的节点,然后我需要将分配中的小时数替换为距比赛地点数小时。 所以生成的 xslt 看起来像 -

<?xml version="1.0" encoding="UTF-8"?>
<Data>
    <id>1</id>
    <some_data></some_data>
    <other_data></other_data>
    <allocation>
        <date>16-10-2023</date>
        <hours>1</hours>
    </allocation>
    <allocation>
        <date>23-10-2023</date>
        <hours>5</hours>
    </allocation>
    <allocation>
        <date>30-10-2023</date>
        <hours>3</hours>
    </allocation>
    <allocation>
        <date>06-11-2023</date>
        <hours>10</hours>
    </allocation>
</Data>

我尝试过使用-

 <xsl:variable name="vid" select="entry/id"/>
        <xsl:variable name="vExtendAppForecast" >
            <xsl:copy-of select="entry/line_data"/>
        </xsl:variable>
<xsl:for-each select=set1/line_data[id=$vid]/allocation>
<xsl:variable name="vStartDate" select="date"/>
<xsl:choose>
<xsl:when test="exists($vExtendAppForecast[week_hours/wd:start_date=$vStartDate]")
 -- replace hours with hours from variable
<xsl:when>
<xsl:otherwise>
 <xsl:copy-of select="current()"/>
<xsl:otherwise>
</choose>
xml xslt-2.0
1个回答
0
投票

首先,您正在制作一个完全不必要的子树副本。可以更换

<xsl:variable name="vExtendAppForecast" >
    <xsl:copy-of select="entry/line_data"/>
</xsl:variable>

<xsl:variable name="vExtendAppForecast" select="entry/line_data"/>

但这与你的问题无关。

最简单的方法是使用习惯用法

(X, Y)[1]
(假设 X 最多只能返回一项)如果存在则返回 X,否则返回 Y。这意味着您可以将整个
xsl:choose
替换为:

<allocation>
  <xsl:copy-of select="$vStartDate"/>
  <hours>
     <xsl:value-of 
          select="($vExtendAppForecast[week_hours/wd:start_date=$vStartDate]/time_hr,
                  .)[1]"/>
  </hours>
</allocation>

我还没有测试这会产生完全正确的输出,但希望它能说明这个想法。

习语

(X, Y)[1]
非常常见,因此 XSLT 4.0 的提案中包含了一个运算符
X otherwise Y

© www.soinside.com 2019 - 2024. All rights reserved.