访问外部元素内部for-each

时间:2017-01-19 01:27:47

标签: xslt-1.0

我在尝试访问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>

我正在尝试显示“//Tool/sta.time”的值,其顺序与@ T.number相同。任何想法我将如何做/构造这个?

2 个答案:

答案 0 :(得分:0)

您可以利用工作元素和工具元素的位置将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)]">,您可能有两个(或更多?)Job元素具有相同的T.number,并且您希望将它们视为一个。为此,我建议使用muenchian分组来保存具有唯一T.number的作业,然后将它们的位置与vsortOrder中存在的工具元素的位置相匹配。

答案 1 :(得分:0)

---根据说明进行编辑---

选择Tool与当前number的{​​{1}}匹配的T.number的首选方法是定义 key as:

Job

然后将其用作:

<xsl:key name="tool" match="Tool" use="@number" />

另请注意:

<xsl:value-of select="format-number(key('tool', @T.number)/@sta.time div 60,'0.00')"/>

不是消除重复的好方法。您应该使用Muenchian method代替,如以下样式表所示:

XSLT 1.0

<xsl:for-each select="//Job[not(@T.number=preceding::Job/@T.number)]">

当这个应用于您的输入示例时,结果将是:

<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>

这与您的问题中显示的结果不同 - 但我怀疑这是正确的结果。