Как выполнить Inner Join для 2 таблиц XML, чтобы получить 1 вложенную таблицу с помощью XSLT? - PullRequest
0 голосов
/ 30 октября 2018

у меня есть 3 таблицы XML ITAB, TAB и TAB1. У ITAB есть операционная ценность, информация о которой у нас есть в TAB.

    <root>


        <ITAB>
        <DATA>
            <OPERATION>O_WORK_ORDER_1</OPERATION>
        </DATA>
        <DATA>
        <OPERATION>O_WORK_ORDER_2</OPERATION>
        </DATA>
    </ITAB>

    <TAB>
        <DATA>
            <OPERATION>O_WORK_ORDER_1</OPERATION>
            <WORKINSTRUCTION>CASCADION</WORKINSTRUCTION>
            <CODE>CODEXX1</CODE>
            <REVISION>111REV1</REVISION>
        </DATA>
        <DATA>
            <OPERATION>O_WORK_ORDER_1</OPERATION>
            <WORKINSTRUCTION>CASCADION</WORKINSTRUCTION>
            <CODE>CODEXX1</CODE>
            <REVISION>111REV1</REVISION>
        </DATA>

        <DATA>
            <OPERATION>O_WORK_ORDER_2</OPERATION>
            <WORKINSTRUCTION>CASCADION2</WORKINSTRUCTION>
            <CODE>CODEXX2</CODE>
            <REVISION>111REV2</REVISION>
        </DATA>
    </TAB>

    <TAB1>
        <DATA>
            <OPERATION>O_WORK_ORDER_1</OPERATION>
            <DCPARAMETER>TESTPARAMETER1</DCPARAMETER>
            <DCVALUE>TEMP111</DCVALUE>
            <DCRESULT>PASS</DCRESULT>
        </DATA>
        <DATA>
            <OPERATION>O_WORK_ORDER_2</OPERATION>
            <DCPARAMETER>TESTPARAMETER2</DCPARAMETER>
            <DCVALUE>TEMP112</DCVALUE>
            <DCRESULT>FAIL</DCRESULT>
        </DATA>
    </TAB1>

</root>

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

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
  <html>
<body>


    <table border="1">
      <tr bgcolor="#9acd32">
      <th>OPERATION</th>  
      <th>Table</th>
    </tr>
    <xsl:for-each select="ITAB/DATA">

      <tr>
        <td><xsl:value-of select="OPERATION"/></td>  
        <xsl:variable name="Operation" select="OPERATION"/>     
        <td><xsl:apply-templates select="OPERATION"></td>
      </tr>

    </xsl:for-each>
    </table>

</body>
</html>
</xsl:template>
<xsl:template match="OPERATION">
    <table border="1">
      <tr bgcolor="#9acd32">
      <th>OPERATION</th>
      <th>WORKINSTRUCTION</th>
      <th>REVISION</th>      
    </tr>
    <xsl:for-each select="TAB/DATA">
    <xsl:if test="OPERATION={$Operation}">
      <tr>
        <td><xsl:value-of select="OPERATION"/></td>
        <td><xsl:value-of select="WORKINSTRUCTION"/></td>
        <td><xsl:value-of select="REVISION"/></td>        
      </tr>
    </xsl:if>
    </xsl:for-each>
    </table>
</xsl:template>
</xsl:stylesheet>

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

1 Ответ

0 голосов
/ 30 октября 2018

Боюсь, что с вашим XSLT довольно много проблем, хотя ни одно из них трудно решить ...

  1. В вашем шаблоне соответствует /, вы делаете <xsl:for-each select="ITAB/DATA">, но / соответствует узлу документа, который является родителем вашего root элемента. Следовательно, ваше предложение select ничего не выберет. Вы должны изменить шаблон, чтобы он соответствовал /root (или просто root)
  2. XSLT не является правильно сформированным XML, как вы делаете <xsl:apply-templates select="OPERATION">, который не является закрытым. Это должно быть <xsl:apply-templates select="OPERATION" />
  3. Переменные являются локальными для блока, в котором они объявлены, поэтому текущее объявление $Operation будет фактически доступно только с блоком <tr>...</tr>. На самом деле вы можете просто переместить объявление в шаблон, соответствующий OPERATION (где он должен был бы стать <xsl:variable name="Operation" select="."/>, поскольку текущий узел будет OPERATION на этом этапе.
  4. <xsl:if test="OPERATION={$Operation}"> недопустимый синтаксис. Это должно быть просто <xsl:if test="OPERATION=$Operation">, потому что XSLT уже ожидал выражения здесь.
  5. На самом деле вам вообще не нужен xsl:if, потому что вы можете добавить его к xsl:for-each примерно так ... <xsl:for-each select="TAB/DATA[OPERATION=$Operation]">
  6. На самом деле, это тоже не сработает, потому что вы в настоящее время сопоставляете узел OPERATION, вложенный в элемент ITAB, и у него нет TAB как дочернего элемента. Вы действительно хотите выбрать TAB/DATA в другом месте документа. Итак, вы должны сделать <xsl:for-each select="//TAB/DATA[OPERATION=$Operation]">

Попробуйте это XSLT ....

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="root">
 <html>
  <body>
   <table border="1">
    <tr bgcolor="#9acd32">
     <th>OPERATION</th>  
     <th>Table</th>
    </tr>
    <xsl:for-each select="ITAB/DATA">
     <tr>
      <td><xsl:value-of select="OPERATION"/></td>  
      <td><xsl:apply-templates select="OPERATION" /></td>
     </tr>
    </xsl:for-each>
   </table>
  </body>
 </html>
</xsl:template>

<xsl:template match="OPERATION">
 <xsl:variable name="Operation" select="."/>     
 <table border="1">
  <tr bgcolor="#9acd32">
   <th>OPERATION</th>
   <th>WORKINSTRUCTION</th>
   <th>REVISION</th>      
  </tr>
  <xsl:for-each select="//TAB/DATA[OPERATION=$Operation]">
   <tr>
    <td><xsl:value-of select="OPERATION"/></td>
    <td><xsl:value-of select="WORKINSTRUCTION"/></td>
    <td><xsl:value-of select="REVISION"/></td>        
   </tr>
  </xsl:for-each>
 </table>
</xsl:template>
</xsl:stylesheet>

Сказав, что, как уже упоминалось в комментариях, гораздо лучше использовать xsl:key для поиска данных из других частей документа XML.

Итак, определите ключ следующим образом:

<xsl:key name="tabs" match="TAB/DATA" use="OPERATION" />

И получить соответствующие узлы, как ...

<xsl:for-each select="key('tabs', $Operation)">

На самом деле вам не нужно здесь использовать переменную. Попробуйте это XSLT тоже:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="tabs" match="TAB/DATA" use="OPERATION" />

<xsl:template match="root">
 <html>
  <body>
   <table border="1">
    <tr bgcolor="#9acd32">
     <th>OPERATION</th>  
     <th>Table</th>
    </tr>
    <xsl:for-each select="ITAB/DATA">
     <tr>
      <td><xsl:value-of select="OPERATION"/></td>  
      <td><xsl:apply-templates select="OPERATION" /></td>
     </tr>
    </xsl:for-each>
   </table>
  </body>
 </html>
</xsl:template>

<xsl:template match="OPERATION">
 <table border="1">
  <tr bgcolor="#9acd32">
   <th>OPERATION</th>
   <th>WORKINSTRUCTION</th>
   <th>REVISION</th>      
  </tr>
  <xsl:for-each select="key('tabs', .)">
   <tr>
    <td><xsl:value-of select="OPERATION"/></td>
    <td><xsl:value-of select="WORKINSTRUCTION"/></td>
    <td><xsl:value-of select="REVISION"/></td>        
   </tr>
  </xsl:for-each>
 </table>
</xsl:template>
</xsl:stylesheet>

См. Это в действии на http://xsltfiddle.liberty -development.net / pPqsHUi

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...