Как реализовать сбор узлов по логике - PullRequest
0 голосов
/ 06 апреля 2020

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

enter image description here

Кроме того, я добавляю мой html файл:

<html>
   <body>
      <h1>example_2</h1>
      <table border="1">
         <tr>
            <td></td>
            <td>global_structure in a code_1</td>
            <td></td>
            <td>global_structure in a code_2</td>
            <td></td>
         </tr>
         <tr>
            <td>name of the file</td>
            <td></td>
         </tr>
         <tr>
            <td>skip</td>
            <td>text_var</td>
            <td>text</td>
            <td>funktion</td>
            <td>A1</td>
            <td></td>
         </tr>
         <tr>
            <td>skip</td>
            <td></td>
            <td></td>
            <td>funktion</td>
            <td>A2</td>
            <td></td>
         </tr>
         <tr>
            <td>skip</td>
            <td></td>
            <td></td>
            <td>var</td>
            <td>A2_var</td>
            <td></td>
         </tr>
         <tr>
            <td>skip</td>
            <td></td>
            <td></td>
            <td>funktion</td>
            <td>A3</td>
            <td></td>
         </tr>
         <tr>
            <td>skip</td>
            <td></td>
            <td></td>
            <td>var</td>
            <td>A3_var1</td>
            <td></td>
         </tr>
         <tr>
            <td>skip</td>
            <td></td>
            <td></td>
            <td>var</td>
            <td>A3_var2</td>
            <td></td>
         </tr>
         <tr>
            <td>name of the file_2</td>
            <td></td>
         </tr>
         <tr>
            <td>skip</td>
            <td>text_var</td>
            <td>text</td>
            <td>funktion</td>
            <td>A1</td>
            <td></td>
         </tr>
         <tr>
            <td>skip</td>
            <td></td>
            <td></td>
            <td>funktion</td>
            <td>A2</td>
            <td></td>
         </tr>
         <tr>
            <td>skip</td>
            <td></td>
            <td></td>
            <td>var</td>
            <td>A2_var</td>
            <td></td>
         </tr>
         <tr>
            <td>skip</td>
            <td></td>
            <td></td>
            <td>funktion</td>
            <td>A3</td>
            <td></td>
         </tr>
         <tr>
            <td>skip</td>
            <td></td>
            <td></td>
            <td>var</td>
            <td>A3_var1</td>
            <td></td>
         </tr>
         <tr>
            <td>skip</td>
            <td></td>
            <td></td>
            <td>var</td>
            <td>A3_var2</td>
            <td></td>
         </tr>
         <tr>
            <td>end</td>
            <td></td>
         </tr>
         <tr>
            <td></td>
         </tr>
      </table>
   </body>
</html>

Например, файл с именем файла: "имя файла" должен иметь следующий код

global_structure in a code_1(){
text;
};

global_structure in a code_2(){
A1();
A2(A2_var);
A3(A3_var1,A3_var2);
};

Идея состоит в том, что если парсер сталкивается с любым "var", он должен вставьте его в «функцию». Если после функции нет изменений, функция должна быть вставлена ​​без каких-либо переменных. У меня проблемы с этим, я уже задавал вопрос, как рассчитать количество строк между файлами (skip-sequence). Но я не могу понять, как я могу использовать эту функцию для любой рекурсивной функции, потому что она дает мне два числа, как они есть. Теперь для каждой итерации моей структуры. Пожалуйста, дайте мне какие-либо советы, как это реализовать. Я очень новичок в xslt:)

Вот моя ссылка на код: https://xsltfiddle.liberty-development.net/bwe3c5/54

 <xsl:template match="/html/body/table">

   <xsl:param name ="counter_var" select="mf:skip-sequences(.)" />

   <!--name of the file-->
   <xsl:for-each select="./tr">
       <xsl:if test = "not(child::td[1] ='skip') or not(string(child::td[1]))">
           <xsl:variable name ="new_file_name" select="child::td[1]" />

             <xsl:value-of select="child::td[1]"/>
             <xsl:text>&#xa;</xsl:text>
       </xsl:if>
   </xsl:for-each>


   <!--global_structure in a code-->
   <xsl:for-each select="./tr[1]/td">

       <xsl:choose>
       <xsl:when test="position() mod 2=0">
           <xsl:call-template name="filtering_a_position">
           <xsl:with-param name="position" select="position()">
           </xsl:with-param>
           </xsl:call-template>
       </xsl:when>
     </xsl:choose>
     </xsl:for-each>
   </xsl:template>




    <xsl:template name="filtering_a_position">

    <xsl:param name="position"/>
    <xsl:text>&#xa;xsl:value-of select="../td[$position]"&#xa;</xsl:text>
    <xsl:value-of select="../td[$position]"/>
    <xsl:text>&#xa;</xsl:text>
    <xsl:for-each select="/html/body/table/tr/td[$position+1]">
    <xsl:value-of select="current()"/> <xsl:text>&#xa;</xsl:text>
    </xsl:for-each>



    </xsl:template>

<xsl:function name="mf:skip-sequences" as="xs:integer*">
     <xsl:param name="table" as="element(table)"/>
     <xsl:for-each-group select="$table/tr" group-adjacent="boolean(self::tr[td[1] = 'skip'])">
         <xsl:sequence select="count(current-group())[current-grouping-key()]"/>
     </xsl:for-each-group>
 </xsl:function>

 <xsl:template match="table">
     <xsl:sequence select="mf:skip-sequences(.)"/>
 </xsl:template>



</xsl:stylesheet>

1 Ответ

2 голосов
/ 06 апреля 2020

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

Я бы начал путем определения промежуточного представления данных, которое отражает его логическую структуру. Это может выглядеть примерно так:

<files>
  <file name="file1">
    <structure in="code1">
      <entry type="text_var" name="text"/>
    </structure>
    <structure in="code2">
      <entry type="funktion" name="A1"/>
      <entry type="funktion" name="A2"/>
      <entry type="var" name="A2_var"/>
      ... etc ...

(возможно, я ошибся; я не претендую на понимание ваших данных или их истинной структуры).

Первый этап преобразование (чтобы добраться до этой структуры из вашего начального ввода) может быть выполнено с использованием <xsl:for-each-group select="tr" group-starting-with="tr[td[1] ne 'skip']">.

Второй этап также включает позиционную группировку, на этот раз что-то вроде <xsl:for-each-group select="entry" group-starting-with="entry[@type='funktion'">.

Я знаю это всего лишь набросок подхода к решению, но я надеюсь, что это продвинет вас вперед.

...