我在尝试访问 for-each 循环之外的元素时遇到问题。 这是我的 XML。
<JobList sta.time="151.879">
<Job T.number="7" T.identifier="Tool" T.holder.comment="Holder" sta.time="30.789" />
<Job T.number="5" T.identifier="Second" T.holder.comment="secholder" sta.time="35.567" />
<Job T.number="7" T.identifier="Tool" T.holder.comment="Holder" sta.time="4.778" />
<Job T.number="5" T.identifier="Second" T.holder.comment="secholder" sta.time="80.745" />
<Tool sta.time="116.312" number="5" />
<Tool sta.time="35.567" number="7" />
</JobList>
这是我的 XSL 的摘录
<table width="100%" border="1">
<thead>
<tr>
<td>Numbers</td>
<td>Description</td>
<td>Holder</td>
<td>Time</td>
</tr>
</thead>
<tbody>
<xsl:variable name="vsortOrder" select="//Job[@T.number]" />
<xsl:for-each select="//Job[not(@T.number=preceding::Job/@T.number)]">
<tr>
<td>
<xsl:value-of select="@T.number" />
</td>
<td>
<xsl:value-of select="@T.identifier" />
</td>
<td>
<xsl:value-of select="@T.holder.comment" />
</td>
</xsl:for-each>
<xsl:for-each select="//Tool[$vsortOrder/Job/@T.number]">
<td>
<xsl:value-of select="format-number(@sta.time div 60,'#0.00')" />
</td>
</tr>
</xsl:for-each>
</tbody>
</table>
期望输出:
<div>
<h1>
<table width="100%" border="1">
<thead>
<tr>
<td>Numbers</td>
<td>Description</td>
<td>Holder</td>
<td>Time</td>
</tr>
</thead>
<tbody>
<tr>
<td>7</td>
<td>Tool</td>
<td>Holder</td>
<td>0.59</td>
</tr>
<tr>
<td>5</td>
<td>Second</td>
<td>secholder</td>
<td>1.93</td>
</tr>
</tbody>
</table>
</h1>
</div>
我正在尝试以与@T.number相同的顺序显示"//Tool/sta.time"的值。 任何想法我将如何做到这一点/构建这个?
---根据澄清进行了编辑---
选择其number
与当前Job
T.number
匹配的Tool
的首选方法是将键定义为:
<xsl:key name="tool" match="Tool" use="@number" />
然后将其用作:
<xsl:value-of select="format-number(key('tool', @T.number)/@sta.time div 60,'0.00')"/>
另请注意,这:
<xsl:for-each select="//Job[not(@T.number=preceding::Job/@T.number)]">
不是消除重复项的好方法。您应该改用 Muenchian 方法,如以下样式表所示:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:key name="job" match="Job" use="@T.number" />
<xsl:key name="tool" match="Tool" use="@number" />
<xsl:template match="/JobList">
<table width="100%" border="1">
<thead>
<tr>
<td>Numbers</td>
<td>Description</td>
<td>Holder</td>
<td>Time</td>
</tr>
</thead>
<tbody>
<xsl:for-each select="Job[count(. | key('job', @T.number)[1]) = 1]">
<tr>
<td>
<xsl:value-of select="@T.number" />
</td>
<td>
<xsl:value-of select="@T.identifier" />
</td>
<td>
<xsl:value-of select="@T.holder.comment" />
</td>
<td>
<xsl:value-of select="format-number(key('tool', @T.number)/@sta.time div 60,'0.00')"/>
</td>
</tr>
</xsl:for-each>
</tbody>
</table>
</xsl:template>
</xsl:stylesheet>
当将其应用于您的输入示例时,结果将是:
<table width="100%" border="1">
<thead>
<tr>
<td>Numbers</td>
<td>Description</td>
<td>Holder</td>
<td>Time</td>
</tr>
</thead>
<tbody>
<tr>
<td>7</td>
<td>Tool</td>
<td>Holder</td>
<td>0.59</td>
</tr>
<tr>
<td>5</td>
<td>Second</td>
<td>secholder</td>
<td>1.94</td>
</tr>
</tbody>
</table>
这与你问题中显示的结果不同——但我怀疑这是正确的结果。
您可以利用作业元素和工具元素的位置将Job
映射到Tool
。由于 Job 的首次出现对应于源 XML 中 Tool 元素的首次出现,因此请执行如下操作:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes"/>
<xsl:template match="/">
<table width="100%" border="1">
<thead>
<tr>
<td>Numbers</td>
<td>Description</td>
<td>Holder</td>
<td>Time</td>
</tr>
</thead>
<tbody>
<xsl:variable name="vsortOrder" select="//Tool" />
<xsl:for-each select="//Job[not(@T.number=preceding::Job/@T.number)]">
<tr>
<td>
<xsl:value-of select="@T.number" />
</td>
<td>
<xsl:value-of select="@T.identifier" />
</td>
<td>
<xsl:value-of select="@T.holder.comment" />
</td>
<td>
<xsl:variable name="job-position" select="position()"/>
<xsl:value-of select="format-number($vsortOrder[position()=$job-position]/@sta.time div 60,'0.00')"/>
</td>
</tr>
</xsl:for-each>
</tbody>
</table>
</xsl:template>
</xsl:stylesheet>
形成测试<xsl:for-each select="//Job[not(@T.number=preceding::Job/@T.number)]">
,似乎您可能有两个(或更多?具有相同 T 编号的作业元素,并且您希望将它们视为一个。为此,我建议使用 muenchian 分组来保存具有唯一 T.number 的作业,然后将它们的位置与 vsortOrder
中存在的工具元素的位置相匹配。