2015-11-12 4 views
0

Я новичок в XSL и работаю с очень большой и сложной базой данных, и я нахожусь в тупике.XSL для каждого уникального значения Do

Хотя я не могу обсуждать все детали или делиться спецификой XML, я могу сказать вам, что это разбивка сложной системы, состоящей из других сложных систем, состоящих из сырья. Существует множество слоев информации.

В этом случае мне нужно извлечь описание одного из подкомпонентов конкретного типа подсборки в системе. Возможно, и типично, чтобы эти подкомпоненты использовались несколько раз в подсборке, а подузлы также могут использоваться несколько раз в системе.

В этом случае, если возникает дубликат, мне нужно проигнорировать его. Кроме того, если уникальное значение существует, но встречается не в том месте, его также нужно игнорировать.

Когда такой элемент будет найден, я извлечу его описание. (Обратите внимание, что пока я извлекаю описания, меня не интересует уникальное описание, только элемент, с которым он связан.)

Я использую следующий код (см. XSL ниже), чтобы развернуть некоторые из самых основных подузлов, игнорируя элементы, которые происходят в неправильных процессах, без каких-либо проблем, кроме дубликатов, которые происходят в правильном процессе и отвечают другим требованиям.

Как вы увидите, я устанавливаю значение переменной, которая позже будет отображаться в ячейке таблицы. Этот процесс также хорошо работает.

Мне просто нужно знать, как изменить этот код, чтобы отфильтровывать дубликаты.

Я попытался несколько <xsl:key> и preceding подходов, в том числе нескольких вариаций Meunchian Группировки, но никто из них не работал до сих пор. (Чтобы быть справедливым, я не на 100% уверен, что я правильно их ввел, хотя, как я считаю, я это сделал.) В некоторых случаях такие формулы не возвращают результата (они вызывают пустую ячейку в таблице.), А в других они, кажется, вытирают вне блока кода под ними. (Или они делают бесконечно большую пустую ячейку, которая заполняет оставшуюся часть страницы.)

Любые предложения были бы высоко оценены!

XML

<design> 
    <operation> 
    <operation uom="" trantag="operation">10</operation> 
     <layer> 
      <layerno>10</layerno> 
      <process trntag="NOT_SINGLES">NOT_SINGLES</process> 
      <bom> 
       <position>10</position> 
       <bomitem uom="" trantag="item">ITEM1</bomitem> 
       <description>DESCRIPTION_I1</description> 
      </bom> 
      <bom> 
       <position>20</position> 
       <bomitem uom="" trantag="item">X1</bomitem> 
       <description>DESCRIPTION_X1</description> 
      </bom> 
     </layer> 
    </operation> 
    <subdesign> 
     <design> 
      <operation> 
       <operation uom="" trantag="operation">10</operation> 
        <layer> 
         <layerno>10</layerno> 
         <process trntag="NOT_SINGLES">NOT_SINGLES</process> 
         <bom> 
          <position>10</position> 
          <bomitem uom="" trantag="item">X2</bomitem> 
          <description>DESCRIPTION_X2</description> 
         </bom> 
         <bom> 
          <position>20</position> 
          <bomitem uom="" trantag="item">X3</bomitem> 
          <description>DESCRIPTION_X3</description> 
         </bom> 
         <bom> 
          <position>30</position> 
          <bomitem uom="" trantag="item">ITEM1</bomitem> 
          <description>DESCRIPTION_I1</description> 
         </bom> 
        </layer> 
        <layer> 
         <layerno>20</layerno> 
         <process trntag="NOT_SINGLES">NOT_SINGLES</process> 
         <bom> 
          <position>10</position> 
          <bomitem uom="" trantag="item">X4</bomitem> 
          <description>DESCRIPTION_X4</description> 
         </bom> 
        </layer> 
      </operation> 
      <operation> 
       <operation uom="" trantag="operation">20</operation> 
        <layer> 
         <layerno>10</layerno> 
         <process trntag="NOT_SINGLES">NOT_SINGLES</process> 
         <bom> 
          <position>10</position> 
          <bomitem uom="" trantag="item">X3</bomitem> 
          <description>DESCRIPTION_X3</description> 
         </bom> 
        </layer> 
        <layer> 
         <layerno>20</layerno> 
         <process trntag="NOT_SINGLES">NOT_SINGLES</process> 
         <bom> 
          <position>10</position> 
          <bomitem uom="" trantag="item">X5</bomitem> 
          <description>DESCRIPTION_X5</description> 
         </bom> 
        </layer> 
      </operation> 
     </design> 
     <design> 
      <operation> 
       <operation uom="" trantag="operation">10</operation> 
        <layer> 
         <layerno>10</layerno> 
         <process trntag="NOT_SINGLES">NOT_SINGLES</process> 
         <bom> 
          <position>10</position> 
          <bomitem uom="" trantag="item">X2</bomitem> 
          <description>DESCRIPTION_X2</description> 
         </bom> 
         <bom> 
          <position>20</position> 
          <bomitem uom="" trantag="item">X6</bomitem> 
          <description>DESCRIPTION_X6</description> 
         </bom> 
         <bom> 
          <position>30</position> 
          <bomitem uom="" trantag="item">ITEM1</bomitem> 
          <description>DESCRIPTION_I1</description> 
         </bom> 
        </layer> 
        <layer> 
         <layerno>20</layerno> 
         <process trntag="NOT_SINGLES">NOT_SINGLES</process> 
         <bom> 
          <position>10</position> 
          <bomitem uom="" trantag="item">X7</bomitem> 
          <description>DESCRIPTION_X7</description> 
         </bom> 
        </layer> 
      </operation> 
      <operation> 
       <operation uom="" trantag="operation">20</operation> 
        <layer> 
         <layerno>10</layerno> 
         <process trntag="SINGLES">SINGLES</process> 
         <bom> 
          <position>10</position> 
          <bomitem uom="" trantag="item">ITEM1</bomitem> 
          <description>DESCRIPTION_I1</description> 
         </bom> 
        </layer> 
        <layer> 
         <layerno>20</layerno> 
         <process trntag="SINGLES">SINGLES</process> 
         <bom> 
          <position>10</position> 
          <bomitem uom="" trantag="item">X5</bomitem> 
          <description>DESCRIPTION_X5</description> 
         </bom> 
        </layer> 
      </operation> 
      <operation> 
       <operation uom="" trantag="operation">30</operation> 
        <layer> 
         <layerno>10</layerno> 
         <process trntag="SINGLES">SINGLES</process> 
         <bom> 
          <position>10</position> 
          <bomitem uom="" trantag="item">ITEM2</bomitem> 
          <description>DESCRIPTION_I2</description> 
         </bom> 
        </layer> 
        <layer> 
         <layerno>20</layerno> 
         <process trntag="SINGLES">SINGLES</process> 
         <bom> 
          <position>10</position> 
          <bomitem uom="" trantag="item">X8</bomitem> 
          <description>DESCRIPTION_X8</description> 
         </bom> 
        </layer> 
      </operation> 
      <operation> 
       <operation uom="" trantag="operation">40</operation> 
        <layer> 
         <layerno>10</layerno> 
         <process trntag="SINGLES">SINGLES</process> 
         <bom> 
          <position>10</position> 
          <bomitem uom="" trantag="item">ITEM1</bomitem> 
          <description>DESCRIPTION_I1</description> 
         </bom> 
        </layer> 
        <layer> 
         <layerno>20</layerno> 
         <process trntag="SINGLES">SINGLES</process> 
         <bom> 
          <position>10</position> 
          <bomitem uom="" trantag="item">X1</bomitem> 
          <description>DESCRIPTION_X1</description> 
         </bom> 
        </layer> 
      </operation> 
     </design> 
    </subdesign> 
</design> 

XSL

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" 
       xmlns:oldxsl="http://www.w3.org/TR/WD-xsl" 
       xmlns:msxsl="urn:schemas-microsoft-com:xslt" 
       xmlns:local="#local-functions"> 

<xsl:template match="/"> 

<html> 

<xsl:variable name="result"> 

    <xsl:for-each select="/design/subdesign/design/operation/layer[process = 'SINGLES']"> 

     <xsl:variable name="test" select="bom/bomitem"/> 
      <xsl:if test="starts-with($test,'ITEM')"> 
       <xsl:variable name="print" select="bom/description"/> 
        <xsl:value-of select="$print"/><xsl:text><![CDATA[<br />]]></xsl:text> 
      </xsl:if> 

    </xsl:for-each> 

</xsl:variable> 

<table style="width:4.0in; border:0; table-layout: fixed"> 

    <tr> 
     <td colspan="3" style="vertical-align: top;"> 
      Result : 
     </td> 
     <td colspan="5"> 
      <xsl:value-of select="$result"/> 
     </td> 
    </tr> 

</table> 

</html> 

</xsl:template> 

</xsl:stylesheet> 

Это, неправильно, выход:

Result:  DESCRIPTION_I1 
       DESCRIPTION_I2 
       DESCRIPTION_I1 

Желаемый результат будет:

Result:  DESCRIPTION_I1 
       DESCRIPTION_I2 

Спасибо.

Я использую XLST 1.0.

+0

Если это «необходимо», это потребует времени. Это очень, очень, очень большая и сложная база данных, заполненная запатентованной информацией, используя очень длинную таблицу стилей XSL, чтобы отсортировать ее все ... Наверняка есть способ решить проблему без этого? – Simcik

+0

@Simcik Просто составите простой пример, демонстрирующий проблему (чем проще, тем лучше). В противном случае мы не знаем, к чему относится ваш код. Также укажите, используете ли XSLT 1.0 или 2.0. –

+1

Устранение дубликатов или группировка в XSLT 1.0 требует довольно неинтуитивного шаблона кодирования, известного как Muenchian Grouping. Вам нужно изучить его.Я не знаю, делали ли вы это, когда говорили, что пытаетесь использовать ключи, но если вы что-то пробовали, и это не сработало, мы можем помочь вам, если вы скажете нам, что именно вы пытались и как именно не смогли. –

ответ

0

Я имел в виду, чтобы этот пост здесь раньше, но отвлекся. Здесь было решение, которое сработало для меня:

Как было предложено Даниэлем, и, как определено путем следа и ошибки, xsl:key не может содержаться в тегах HTML (как я и пытался сделать), и не может быть объявлен внутри xsl:template теги.

Перемещая xsl:key в самом начале таблицы стилей, используя его, чтобы помочь определить значение в xsl:variable, а затем вызвать это значение позже в HTML разделе, я был в состоянии достичь желаемых результатов.

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

XSL:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" 
    xmlns:oldxsl="http://www.w3.org/TR/WD-xsl" 
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" 
    xmlns:local="#local-functions" 
    xmlns:date="http://exslt.org/dates-and-times"> 

<!-- KEYS --> 

    <xsl:key name="desc" match="/design/subdesign/design/operation/layer[process = 'SINGLES']/bom[starts-with(bomitem,'ITEM')]" use="description"/> 

<!-- XSL & VARIABLES --> 

<xsl:template match="/"> 

    <xsl:variable name="result"> 
     <xsl:for-each select="/design/subdesign/design/operation/layer[process = 'SINGLES']/bom[starts-with(bomitem,'ITEM')][count(. | key('desc', description)[1]) = 1]"> 
      <xsl:value-of select="description"/><br/> 
     </xsl:for-each> 
    </xsl:variable> 

<!-- HTML --> 

<html> 

    <table style="width:4.0in; border:0; table-layout: fixed"> 

     <tr> 
      <td colspan="3" style="vertical-align: top;"> 
       Result : 
      </td> 
      <td colspan="5"> 
       <xsl:value-of select="$result"/> 
      </td> 
     </tr> 

    </table> 

</html> 
</xsl:template> 
</xsl:stylesheet> 

HTML Выход:

<html> 
    <table style="width:4.0in; border:0; table-layout: fixed"> 
     <tr> 
      <td colspan="3" style="vertical-align: top;"> Result : </td> 
      <td colspan="5">DESCRIPTION_I1<br>DESCRIPTION_I2<br></td> 
     </tr> 
    </table> 
</html 

Еще раз спасибо, Даниэль!

0

Я настроил ваш образец XSLT и смог получить правильные результаты. Надеюсь, вы сможете приспособить его к своему реальному коду. (Я не очень хорошо Muenchian группировке, я обычно использую xsl:for-each-group в 2.0.)

XML Input

<design> 
    <operation> 
     <operation uom="" trantag="operation">10</operation> 
     <layer> 
      <layerno>10</layerno> 
      <process trntag="NOT_SINGLES">NOT_SINGLES</process> 
      <bom> 
       <position>10</position> 
       <bomitem uom="" trantag="item">ITEM1</bomitem> 
       <description>DESCRIPTION_I1</description> 
      </bom> 
      <bom> 
       <position>20</position> 
       <bomitem uom="" trantag="item">X1</bomitem> 
       <description>DESCRIPTION_X1</description> 
      </bom> 
     </layer> 
    </operation> 
    <subdesign> 
     <design> 
      <operation> 
       <operation uom="" trantag="operation">10</operation> 
       <layer> 
        <layerno>10</layerno> 
        <process trntag="NOT_SINGLES">NOT_SINGLES</process> 
        <bom> 
         <position>10</position> 
         <bomitem uom="" trantag="item">X2</bomitem> 
         <description>DESCRIPTION_X2</description> 
        </bom> 
        <bom> 
         <position>20</position> 
         <bomitem uom="" trantag="item">X3</bomitem> 
         <description>DESCRIPTION_X3</description> 
        </bom> 
        <bom> 
         <position>30</position> 
         <bomitem uom="" trantag="item">ITEM1</bomitem> 
         <description>DESCRIPTION_I1</description> 
        </bom> 
       </layer> 
       <layer> 
        <layerno>20</layerno> 
        <process trntag="NOT_SINGLES">NOT_SINGLES</process> 
        <bom> 
         <position>10</position> 
         <bomitem uom="" trantag="item">X4</bomitem> 
         <description>DESCRIPTION_X4</description> 
        </bom> 
       </layer> 
      </operation> 
      <operation> 
       <operation uom="" trantag="operation">20</operation> 
       <layer> 
        <layerno>10</layerno> 
        <process trntag="NOT_SINGLES">NOT_SINGLES</process> 
        <bom> 
         <position>10</position> 
         <bomitem uom="" trantag="item">X3</bomitem> 
         <description>DESCRIPTION_X3</description> 
        </bom> 
       </layer> 
       <layer> 
        <layerno>20</layerno> 
        <process trntag="NOT_SINGLES">NOT_SINGLES</process> 
        <bom> 
         <position>10</position> 
         <bomitem uom="" trantag="item">X5</bomitem> 
         <description>DESCRIPTION_X5</description> 
        </bom> 
       </layer> 
      </operation> 
     </design> 
     <design> 
      <operation> 
       <operation uom="" trantag="operation">10</operation> 
       <layer> 
        <layerno>10</layerno> 
        <process trntag="NOT_SINGLES">NOT_SINGLES</process> 
        <bom> 
         <position>10</position> 
         <bomitem uom="" trantag="item">X2</bomitem> 
         <description>DESCRIPTION_X2</description> 
        </bom> 
        <bom> 
         <position>20</position> 
         <bomitem uom="" trantag="item">X6</bomitem> 
         <description>DESCRIPTION_X6</description> 
        </bom> 
        <bom> 
         <position>30</position> 
         <bomitem uom="" trantag="item">ITEM1</bomitem> 
         <description>DESCRIPTION_I1</description> 
        </bom> 
       </layer> 
       <layer> 
        <layerno>20</layerno> 
        <process trntag="NOT_SINGLES">NOT_SINGLES</process> 
        <bom> 
         <position>10</position> 
         <bomitem uom="" trantag="item">X7</bomitem> 
         <description>DESCRIPTION_X7</description> 
        </bom> 
       </layer> 
      </operation> 
      <operation> 
       <operation uom="" trantag="operation">20</operation> 
       <layer> 
        <layerno>10</layerno> 
        <process trntag="SINGLES">SINGLES</process> 
        <bom> 
         <position>10</position> 
         <bomitem uom="" trantag="item">ITEM1</bomitem> 
         <description>DESCRIPTION_I1</description> 
        </bom> 
       </layer> 
       <layer> 
        <layerno>20</layerno> 
        <process trntag="SINGLES">SINGLES</process> 
        <bom> 
         <position>10</position> 
         <bomitem uom="" trantag="item">X5</bomitem> 
         <description>DESCRIPTION_X5</description> 
        </bom> 
       </layer> 
      </operation> 
      <operation> 
       <operation uom="" trantag="operation">30</operation> 
       <layer> 
        <layerno>10</layerno> 
        <process trntag="SINGLES">SINGLES</process> 
        <bom> 
         <position>10</position> 
         <bomitem uom="" trantag="item">ITEM2</bomitem> 
         <description>DESCRIPTION_I2</description> 
        </bom> 
       </layer> 
       <layer> 
        <layerno>20</layerno> 
        <process trntag="SINGLES">SINGLES</process> 
        <bom> 
         <position>10</position> 
         <bomitem uom="" trantag="item">X8</bomitem> 
         <description>DESCRIPTION_X8</description> 
        </bom> 
       </layer> 
      </operation> 
      <operation> 
       <operation uom="" trantag="operation">40</operation> 
       <layer> 
        <layerno>10</layerno> 
        <process trntag="SINGLES">SINGLES</process> 
        <bom> 
         <position>10</position> 
         <bomitem uom="" trantag="item">ITEM1</bomitem> 
         <description>DESCRIPTION_I1</description> 
        </bom> 
       </layer> 
       <layer> 
        <layerno>20</layerno> 
        <process trntag="SINGLES">SINGLES</process> 
        <bom> 
         <position>10</position> 
         <bomitem uom="" trantag="item">X1</bomitem> 
         <description>DESCRIPTION_X1</description> 
        </bom> 
       </layer> 
      </operation> 
     </design> 
    </subdesign> 
</design> 

XSLT 1,0

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output indent="yes"/> 

    <xsl:key name="desc" match="/design/subdesign/design/operation/layer[process = 'SINGLES']/bom[starts-with(bomitem,'ITEM')]" use="description"/> 

    <xsl:template match="/"> 
    <html> 
     <table style="width:4.0in; border:0; table-layout: fixed"> 
     <tr> 
      <td colspan="3" style="vertical-align: top;"> Result : </td> 
      <td colspan="5"> 
      <xsl:for-each select="/design/subdesign/design/operation/layer[process = 'SINGLES']/bom[starts-with(bomitem,'ITEM')][count(. | key('desc', description)[1]) = 1]"> 
       <xsl:value-of select="description"/> 
       <br/> 
      </xsl:for-each> 
      </td> 
     </tr> 
     </table> 
    </html> 
    </xsl:template> 

</xsl:stylesheet> 

HTML Output

<html> 
 
    <table style="width:4.0in; border:0; table-layout: fixed"> 
 
     <tr> 
 
     <td colspan="3" style="vertical-align: top;"> Result : </td> 
 
     <td colspan="5">DESCRIPTION_I1<br>DESCRIPTION_I2<br></td> 
 
     </tr> 
 
    </table> 
 
</html


Редактировать

Пример использования xsl:variable ...

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output indent="yes"/> 

    <xsl:key name="desc" match="/design/subdesign/design/operation/layer[process = 'SINGLES']/bom[starts-with(bomitem,'ITEM')]" use="description"/> 

    <xsl:template match="/"> 
    <xsl:variable name="results"> 
     <xsl:for-each select="/design/subdesign/design/operation/layer[process = 'SINGLES']/bom[starts-with(bomitem,'ITEM')][count(. | key('desc', description)[1]) = 1]"> 
     <xsl:value-of select="description"/> 
     <br/> 
     </xsl:for-each> 
    </xsl:variable> 
    <html> 
     <table style="width:4.0in; border:0; table-layout: fixed"> 
     <tr> 
      <td colspan="3" style="vertical-align: top;"> Result : </td> 
      <td colspan="5"> 
      <xsl:copy-of select="$results"/> 
      </td> 
     </tr> 
     </table> 
    </html> 
    </xsl:template> 

</xsl:stylesheet> 
+0

Daniel - Спасибо, но это все еще не работает. Я не могу объединить данные таблицы с тестированием переменных, как это было сделано из-за способа форматирования вывода. (Вывод HTML, который у вас выше IS, но он должен быть объединен с другими компонентами [не показаны здесь], которые для всей таблицы. Эта таблица затем помещается в еще большую таблицу.) Я попытался взять то, что у вас есть предложил и изменил его, чтобы информация таблицы не была включена, но она не работает. Смотрите следующий код: – Simcik

+0

@Simcik - Я добавил пример использования 'xsl: variable'. Надеюсь, это поможет. (Вы можете переместить переменную как прямой дочерний элемент 'xsl: stylesheet', если хотите. Было бы более чистым в этом случае.) –

+0

Ну, я понимаю, что вы сделали, и я думаю, что это МОЖЕТ работать, но это требуется LOT модификации в таблице стилей ... Кажется, что 'xsl: key' должен быть объявлен за пределами шаблона' xsl: template', это выполнимо, по крайней мере. Вторая проблема, кажется, намного больше ... Кажется, что код, который вы опубликовали, работает только OUTSIDE из тегов 'html'. Если это так, мне нужно будет сделать еще больше работы, чтобы сделать это решение совместимым. Есть ли способ сделать то, что вы сделали INSIDE из тегов html? Спасибо за помощь! – Simcik

Смежные вопросы