2014-01-20 11 views
0

У меня проблема с моей таблицей стилей XSLT. У меня есть документ XML с несколькими сборками. Каждая сборка имеет уникальный номер позиции. Узел может содержать другие assemblys как позиции, но документ XML имеет плоскую структуру, как это:Структура дерева XSLT на основе номеров позиций

<?xml version="1.0" encoding="ISO-8859-1"?> 
<PartsCatalog Version="1.0"> 
<Description><![CDATA[asdsadasdadad  ]]></Description> 
<Assembly Item="0000   " Plate="   " Class="    "> 
<Description Lang=" DE"><![CDATA[Main assembly]]></Description> 
<Description Lang=" EN"><![CDATA[Main assembly]]></Description> 
<Description Lang=" FR"><![CDATA[Main assembly]]></Description> 
<Description Lang=" IT"><![CDATA[Main assembly]]></Description> 
<Description Lang=" RU"><![CDATA[Main assembly]]></Description> 
<Position PositionNumber=" 10" Item="9284424   " Plate="000020 " Class="    "> 
    <Quantity Unit="st ">  1,0000</Quantity> 
    <Serie From="   " To="   "></Serie> 
    <Characteristic><![CDATA[        ]]></Characteristic> 
    <SparePartFlag><![CDATA[00]]></SparePartFlag> 
    <Description Lang=" DE"><![CDATA[aaaaaa   ]]></Description> 
    <Description Lang=" EN"><![CDATA[aaaaaa   ]]></Description> 
    <Description Lang=" FR"><![CDATA[aaaaaa   ]]></Description> 
    <Description Lang=" IT"><![CDATA[aaaaaa   ]]></Description> 
    <Description Lang=" RU"><![CDATA[        ]]></Description> 
</Position> 
<Position PositionNumber=" 20" Item="9207826   " Plate="104300 " Class="    "> 
    <Quantity Unit="st ">  1,0000</Quantity> 
    <Serie From="   " To="   "></Serie> 
    <Characteristic><![CDATA[10.00-20 PR16     ]]></Characteristic> 
    <SparePartFlag><![CDATA[00]]></SparePartFlag> 
    <Description Lang=" DE"><![CDATA[8 GELAENDEREIFEN    ]]></Description> 
    <Description Lang=" EN"><![CDATA[8 OFFROAD TIRES    ]]></Description> 
    <Description Lang=" FR"><![CDATA[8 PNEUS TOUT-TERRAIN   ]]></Description> 
    <Description Lang=" IT"><![CDATA[8 PNEUMATICI FUORI STRADA  ]]></Description> 
    <Description Lang=" RU"><![CDATA[        ]]></Description> 
</Position> 
<Position PositionNumber=" 30" Item="9178702   " Plate="104280 " Class="    "> 
    <Quantity Unit="st ">  1,0000</Quantity> 
    <Serie From="   " To="   "></Serie> 
    <Characteristic><![CDATA[MH 3       ]]></Characteristic> 
    <SparePartFlag><![CDATA[00]]></SparePartFlag> 
    <Description Lang=" DE"><![CDATA[ZWISCHENRING     ]]></Description> 
    <Description Lang=" EN"><![CDATA[INTERMEDIATE RING    ]]></Description> 
    <Description Lang=" FR"><![CDATA[ENTRETOISE     ]]></Description> 
    <Description Lang=" IT"><![CDATA[ANELLO DISTANZIATORE   ]]></Description> 
    <Description Lang=" RU"><![CDATA[ÏÐÎÊËÀÄÎ×ÍÎÅ ÊÎËÜÖÎ   ]]></Description> 
</Position> 
<Assembly Item="9284424   " Plate="000020 " Class="11100301  "> 
<Description Lang=" DE"><![CDATA[aaaaa   ]]></Description> 
<Description Lang=" EN"><![CDATA[aaaaa   ]]></Description> 
<Description Lang=" FR"><![CDATA[aaaaa   ]]></Description> 
<Description Lang=" IT"><![CDATA[aaaaa   ]]></Description> 
<Description Lang=" RU"><![CDATA[        ]]></Description> 
<Image PositionFrom=" 0">187994</Image> 
<Position PositionNumber=" 100" Item="9284426   " Plate="201000 " Class="110000   "> 
    <Quantity Unit="st ">  1,0000</Quantity> 
    <Serie From="   " To="   "></Serie> 
    <Characteristic><![CDATA[        ]]></Characteristic> 
    <SparePartFlag><![CDATA[20]]></SparePartFlag> 
    <Description Lang=" DE"><![CDATA[OBERWAGEN      ]]></Description> 
    <Description Lang=" EN"><![CDATA[UPPERCARRIAGE     ]]></Description> 
    <Description Lang=" FR"><![CDATA[TOURELLE      ]]></Description> 
    <Description Lang=" IT"><![CDATA[TORRETTA      ]]></Description> 
    <Description Lang=" RU"><![CDATA[ÏÎÂÎÐÎÒÍÀß ÏËÀÒÔÎÐÌÀ   ]]></Description> 
</Position> 
<Position PositionNumber=" 200" Item="9281013   " Plate="102000 " Class="110000   "> 
    <Quantity Unit="st ">  1,0000</Quantity> 
    <Serie From="   " To="   "></Serie> 
    <Characteristic><![CDATA[        ]]></Characteristic> 
    <SparePartFlag><![CDATA[20]]></SparePartFlag> 
    <Description Lang=" DE"><![CDATA[UNTERWAGEN 2PKT.    ]]></Description> 
    <Description Lang=" EN"><![CDATA[UNDERCARRIAGE 2PTS.   ]]></Description> 
    <Description Lang=" FR"><![CDATA[CHASSIS 2PTS.     ]]></Description> 
    <Description Lang=" IT"><![CDATA[CARRO 2STAB.     ]]></Description> 
    <Description Lang=" RU"><![CDATA[        ]]></Description> 
</Position> 
</Assembly> 

Единственный способ определить вспомогательный узел является номером позиции. Я хочу показать XML как древовидную структуру, используя плагин jQuery jsTree. Поэтому мне нужен выход HTML, как это:

<div id="jsTree"> 
<ul> 
    <li>0001 | Main assembly 
    <ul> 
     <li>1111 | Sub assembly 1</li> 
     <li>2222 | Sub assembly 2</li> 
     <li>3333 | Sub assembly 3</li> 
    </ul> 
    </li> 
</ul> 
</div> 

Я пытался использовать много ответов вопросов, подобных моей проблемы до сих пор, но ничего не получалось. Может кто-нибудь мне помочь? Заранее спасибо!

Приветствия B0R0H

+1

Не могли бы вы показать нам, что вы пробовали? –

+0

Я разместил более подробную версию кода ниже. – B0R0H

+0

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

ответ

0

Благодарим вас за помощь! :) Я только что нашел решение проблемы. Я разместил его для других людей, у которых (возможно) есть аналогичная проблема. Этот работал для меня:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions"> 
<xsl:output method="html" encoding="utf-8"/> 
<xsl:variable name="lang-all" select="distinct-values(//Description/@Lang)"/> 
<xsl:template match="/"> 
    <xsl:variable name="doc" select="."/> 
    <xsl:for-each select="$lang-all"> 
     <xsl:variable name="lang" select="."/> 
     <xsl:for-each select="$doc"> 
      <xsl:variable name="filename_index" select="concat('output/',$lang,'/','index','.html')"/> 
      <xsl:variable name="jstree"> 
       <xsl:call-template name="build-list"> 
        <xsl:with-param name="lang" select="$lang" /> 
        <xsl:with-param name="node" select="PartsCatalog/Assembly[1]" /> 
       </xsl:call-template> 
      </xsl:variable> 
      <xsl:value-of select="$filename_index"/> 
      <xsl:result-document href="{$filename_index}"> 
       <html> 
        <head> 
         <meta charset="utf-8"/> 
         <title>ETK</title> 
         <script src="../0jquery/jquery-ui-1.10.3/jquery-1.9.1.js"/> 
         <script src="../0jquery/jquery-ui-1.10.3/ui/jquery-ui.js"/> 
         <script src="../0dropdown/jquery.easydropdown.min.js"/> 
         <script src="../0jstree/dist/jstree.min.js"/> 
         <link rel="stylesheet" href="../0jquery/jquery-ui-themes-1.10.3/themes/smoothness/jquery-ui.css"/> 
         <link rel="stylesheet" href="../0jstree/dist/themes/default/style.min.css" /> 
         <link rel="stylesheet" href="../0dropdown/themes/easydropdown.css" type="text/css"/> 
         <link rel="stylesheet" href="../0css/style.css" type="text/css"/> 
        </head> 
        <body> 
         <div class="head"> 
          <div class="innertube_head"> 
           <h1>ETK</h1> 
          </div> 
         </div> 
         <div class="left"> 
          <div class="jstree_header"> 
           <xsl:value-of select="PartsCatalog/Description"/> 
          </div> 
          <div class="innertube_left" id="jstree"> 
           <xsl:copy-of select="$jstree" /> 
          </div> 
         </div> 
         <div class="center"> 
          <div class="center_top"/> 
          <div class="center_bottom"/> 
         </div> 
         <div class="right"> 
          <div class="3d_frame"></div> 
          <div class="innertube_right"> 
            <select id="countries" class="dropdown"> 
             <option value="#">Change language</option> 
             <option value="../{$lang-all[1]}/index.html">german</option> 
             <option value="../{$lang-all[2]}/index.html">english</option> 
             <option value="../{$lang-all[3]}/index.html">french</option> 
             <option value="../{$lang-all[4]}/index.html">italian</option> 
             <option value="../{$lang-all[5]}/index.html">russian</option> 
            </select> 
            <script> 
             $('#countries').bind('change', function() { 

              var url = $(this).val(); 

              if (url != '') { 
               window.location = url; 
              } 
              return false; 
             }); 
            </script> 
          </div> 
         </div> 
         <script> 
          $(function() { 
          // 6 create an instance when the DOM is ready 
          $('#jstree').jstree(); 

          // 7 bind to events triggered on the tree 
          $('#jstree').on("changed.jstree", function (e, data) { 
           console.log(data.selected); 
          }); 

          // 8 interact with the tree - either way is OK 
          $('button').on('click', function() { 
           $('#jstree').jstree(true).select_node('child_node_1'); 
           $('#jstree').jstree('select_node', 'child_node_1'); 
           $.jstree.reference('#jstree').select_node('child_node_1'); 
          }); 
          }); 
         </script> 
        </body> 
       </html> 
      </xsl:result-document> 
     </xsl:for-each> 
    </xsl:for-each> 
</xsl:template> 
<xsl:template match="Assembly"> 
    <xsl:apply-templates select="Position"/> 
</xsl:template> 
<xsl:template match="Position"> 
    <xsl:param name="lang"/> 
    <TR> 
     <TD> 
      <xsl:value-of select="normalize-space(@PositionNumber)"/> 
     </TD> 
     <TD> 
      <xsl:value-of select="normalize-space(Description[@Lang=$lang])"/> 
     </TD> 
     <TD> 
      <xsl:value-of select="normalize-space(@Item)"/> 
     </TD> 
     <TD> 
      <xsl:value-of select="normalize-space(Quantity)"/> 
     </TD> 
     <TD> 
      <xsl:value-of select="normalize-space(Quantity/@Unit)"/> 
     </TD> 
    </TR> 
</xsl:template> 
<xsl:template name="build-list"> 
<xsl:param name="node"></xsl:param> 
<xsl:param name="lang"></xsl:param> 
    <ul> 
     <xsl:for-each select="$node/Position"> 
      <xsl:variable name="item" select="@Item" /> 
      <xsl:if test="count(//Assembly[@Item = $item]) != 0"> 
       <li> 
        <xsl:value-of select="normalize-space(@Item)"/> | <xsl:value-of select="normalize-space(Description[@Lang=$lang])"/> 
        <xsl:call-template name="build-list"> 
         <xsl:with-param name="node" select="//Assembly[@Item = $item]" /> 
         <xsl:with-param name="lang" select="$lang" /> 
        </xsl:call-template> 
       </li> 
      </xsl:if> 
      <xsl:if test="count(//Assembly[@Item = $item]) = 0"> 
       <li><xsl:value-of select="normalize-space(@Item)"/> | <xsl:value-of select="normalize-space(Description[@Lang=$lang])"/></li> 
      </xsl:if> 
     </xsl:for-each> 
    </ul> 
</xsl:template> 
</xsl:stylesheet> 
1

Вы нужно использовать ключ так, что каждый узел может применяться шаблоны (рекурсивно) к его компонентам:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" > 
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/> 

<xsl:key name="kAssy" match="Assembly" use="@Item" /> 

<xsl:template match="/PartsCatalog"> 
<div id="jsTree"> 
    <ul> 
     <xsl:apply-templates select="Assembly[Description='Main assembly']"/> 
    </ul> 
</div> 
</xsl:template> 

<xsl:template match="Assembly"> 
<li> 
    <xsl:value-of select="@Item"/> 
    <xsl:text> | </xsl:text> 
    <xsl:value-of select="Description"/> 
    <xsl:variable name="mySubs" select="key('kAssy', Position/@Item)" /> 
    <xsl:if test="$mySubs"> 
     <ul> 
      <xsl:apply-templates select="$mySubs"/> 
     </ul> 
    </xsl:if> 
</li> 
</xsl:template> 

</xsl:stylesheet> 
+0

Благодарим за помощь! :) Я решил проблему. :) – B0R0H

+0

@ B0R0H Если ваша проблема решена, пожалуйста, закройте вопрос, приняв один из ответов - или (если ни один из ответов не помог) напишите свой собственный ответ и примите его. –

+0

Я написал свой собственный ответ. Я могу принять это завтра. – B0R0H

0

Основной ответ в том, что вам нужно сделать сверху вниз рекурсивный спуск через данные с использованием xsl: apply-templates в обычном режиме, но с одним исключением: вместо обработки физических дочерних узлов узла в дереве XML вам необходимо обработать свои логические дочерние элементы. Таким образом, вместо написания

<xsl:apply-templates select="child::node()"/> 

, как обычно, вы пишете

<xsl:apply-templates select="//Assembly[@Item = current()/Position/@Item]"/> 

, а затем на следующем этапе является то, что вы можете оптимизировать это с помощью клавиш, как описано michael.hor257k (не обязательно, если вы используя процессор, такой как Saxon-EE, который автоматически выполняет оптимизацию).

+0

Благодарим за помощь! :) Я решил проблему. :) – B0R0H

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