2017-01-19 15 views
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. Любые идеи, как я буду это делать/структурировать это?

+0

Вероятно, это сочетание чрезмерного использования '//', слишком много 'xsl: for-each' и использование' previous :: 'вместо' previous-sibling :: '. Можете ли вы добавить свой желаемый результат, чтобы мы могли предложить некоторые изменения XSLT? –

+0

Я добавил в желаемом результате. –

+0

Ваш результат не имеет смысла: значение 'sta.time', связанное с' T.number = 7', равно 35.567, которое после деления на 60 дает 0.59. Тем не менее вы показываете 0.59 в строке, где T.number = 5. И откуда взялось значение 0.84? –

ответ

0

--- отредактирован с учетом уточнений ---

Предпочтительный способ выбора Tool которого number совпадает с T.number текущего Job является определение key как:

<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 method вместо этого, как показано в следующей таблице стилей:

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> 

Это отличается от результата, указанного в вашем вопросе, но я подозреваю, что это правильный результат.

+0

Я пробовал свой второй XSL-код, и он работает, но я столкнулся с одним вопросом с ним. Я забыл упомянуть в своем вопросе, что элементы «Tool» находятся в числовом порядке по T.number. Поэтому, когда я запускаю ваш код, он не распечатывает sta.time в правильном порядке, и в некоторых областях есть NaN. Я обновил код в вопросе. –

+0

@AlexW Было бы правильным предположить, что 'Job' и' Tool 'связаны общим значением в' T.number' и 'number'? И если да, то какие-то из этих уникальных? Обновите свой пример и покажите любые дубликаты, которые могут возникнуть. –

+0

Да «T.number» - это то же самое, что «число», но «T.number» отсортировано в порядке, в котором мне нужно, чтобы оно отображалось, поэтому я его использовал. Я обновил XML с помощью дубликатов с соответствующими значениями «sta.time», и я очень признателен, что вы помогли мне. –

0

Вы можете использовать позиции ваших элементов работы и элементов инструмента для отображения Job на Tool. Так как первое появление Иова соответствует первому вхождению инструмента элемента в исходном XML, сделать что-то вроде этого:

<?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.number, и вы хотите относиться к ним как к одному. Для этого я бы предложил использовать группировку muenchian для сохранения заданий с уникальным номером T.number, а затем сопоставить их позиции с положением элементов инструмента, присутствующих в vsortOrder.

+1

** 1. ** Вы не можете использовать 'exsl: node-set()' без привязки префикса 'exsl' к его пространству имен в первую очередь. - ** 2. ** Здесь нет необходимости использовать 'exsl: node-set()' здесь; переменная уже является набором узлов. И нет реальной потребности в переменной. –

+0

Спасибо @ michael.hor257k. Я удалил функцию расширения узла. Я придерживаюсь использования переменной, поскольку это часть моего первоначального решения. – Madeyedexter

+0

Я забыл упомянуть в своем вопросе, что элементы «Инструмент» находятся в числовом порядке от T.number. Я обновил вопрос новыми значениями. Когда я попробовал свой код, sta.time не был в правильном порядке. Извините, что не вменяю в мой вопрос. Я не обратил на это внимания. –