我使用 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 节点匹配的节点
<?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>
首先,您正在制作一个完全不必要的子树副本。可以更换
<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
。