2016-01-14 10 views
-1

У меня очень плохо структурированный источник XML, выходящий из нашей системы ERP, и отношения «Родительский/дочерний» для заголовка к деталям обращаются вспять, поскольку во время выполнения parent (key) неизвестно до тех пор, пока первая подробная запись не будет обработана. Это связано с тем, как был написан интерфейс из старого приложения мэйнфрейма DB2. К сожалению, я не имею права изменять отчет и не могу повлиять на изменение отчета, поэтому мне приходится иметь дело с источником как есть.Как реструктурировать XML с помощью XSLT, когда дочерний узел на самом деле является родителем

Вот как выглядит вывод XML как:

<report> 
    <detail> 
     <header> 
      <keyfield>1231</keyfield> 
      <headerfield1>foo</headerfield> 
      <headerfield2>bar</headerfield2> 
     </header> 
     <keymatch>1231</keymatch> 
     <detailfield0>Line1</detailfield0> 
     <detailfield1>this is bad structure</detailfield1> 
     <detailfield2>and not my design</detailfield2> 
    </detail> 
    <detail> 
     <keymatch>1231</keymatch> 
     <detailfield0>Line2</detailfield0> 
     <detailfield1>this is bad structure</detailfield1> 
     <detailfield2>and not my design</detailfield2> 
    </detail> 
    <detail> 
     <keymatch>1231</keymatch> 
     <detailfield0>Line3</detailfield0> 
     <detailfield1>this is bad structure</detailfield1> 
     <detailfield2>and not my design</detailfield2> 
    </detail> 
    <detail> 
     <keymatch>1231</keymatch> 
     <detailfield0>Line4</detailfield0> 
     <detailfield1>this is bad structure</detailfield1> 
     <detailfield2>and not my design</detailfield2> 
    </detail> 
    <detail> 
     <keymatch>1231</keymatch> 
     <detailfield0>Line5</detailfield0> 
     <detailfield1>this is bad structure</detailfield1> 
     <detailfield2>and not my design</detailfield2> 
    </detail> 
    <detail> 
     <header> 
      <keyfield>1232</keyfield> 
      <headerfield1>boo</headerfield> 
      <headerfield2>far</headerfield2> 
     </header> 
     <keymatch>1232</keymatch> 
     <detailfield0>Line1</detailfield0> 
     <detailfield1>this is bad structure</detailfield1> 
     <detailfield2>and not my design</detailfield2> 
    </detail> 
    <detail> 
     <keymatch>1232</keymatch> 
     <detailfield0>Line2</detailfield0> 
     <detailfield1>this is bad structure</detailfield1> 
     <detailfield2>and not my design</detailfield2> 
    </detail> 
    <detail> 
     <keymatch>1232</keymatch> 
     <detailfield0>Line3</detailfield0> 
     <detailfield1>this is bad structure</detailfield1> 
     <detailfield2>and not my design</detailfield2> 
    </detail> 
    <detail> 
     <keymatch>1232</keymatch> 
     <detailfield0>Line4</detailfield0> 
     <detailfield1>this is bad structure</detailfield1> 
     <detailfield2>and not my design</detailfield2> 
    </detail> 
    <detail> 
     <keymatch>1232</keymatch> 
     <detailfield0>Line5</detailfield0> 
     <detailfield1>this is bad structure</detailfield1> 
     <detailfield2>and not my design</detailfield2> 
    </detail> 
</report> 

В конце концов, мне это нужно, чтобы быть в формате, аналогичном следующему:

<report> 
    <header> 
     <keyfield>1231</keyfield> 
     <headerfield1>foo</headerfield> 
     <headerfield2>bar</headerfield2> 
      <detail> 
       <keymatch>1231</keymatch> 
       <detailfield0>Line1</detailfield0> 
       <detailfield1>this is bad structure</detailfield1> 
       <detailfield2>and not my design</detailfield2> 
      </detail> 
      <detail> 
       <keymatch>1231</keymatch> 
       <detailfield0>Line2</detailfield0> 
       <detailfield1>this is bad structure</detailfield1> 
       <detailfield2>and not my design</detailfield2> 
      </detail> 
      <detail> 
       <keymatch>1231</keymatch> 
       <detailfield0>Line3</detailfield0> 
       <detailfield1>this is bad structure</detailfield1> 
       <detailfield2>and not my design</detailfield2> 
      </detail> 
      <detail> 
       <keymatch>1231</keymatch> 
       <detailfield0>Line4</detailfield0> 
       <detailfield1>this is bad structure</detailfield1> 
       <detailfield2>and not my design</detailfield2> 
      </detail> 
      <detail> 
       <keymatch>1231</keymatch> 
       <detailfield0>Line5</detailfield0> 
       <detailfield1>this is bad structure</detailfield1> 
       <detailfield2>and not my design</detailfield2> 
      </detail> 
    </header> 
    <header> 
     <keyfield>1232</keyfield> 
     <headerfield1>boo</headerfield> 
     <headerfield2>far</headerfield2> 
      <detail> 
       <keymatch>1232</keymatch> 
       <detailfield0>Line1</detailfield0> 
       <detailfield1>this is bad structure</detailfield1> 
       <detailfield2>and not my design</detailfield2> 
      </detail> 
      <detail> 
       <keymatch>1232</keymatch> 
       <detailfield0>Line2</detailfield0> 
       <detailfield1>this is bad structure</detailfield1> 
       <detailfield2>and not my design</detailfield2> 
      </detail> 
      <detail> 
       <keymatch>1232</keymatch> 
       <detailfield0>Line3</detailfield0> 
       <detailfield1>this is bad structure</detailfield1> 
       <detailfield2>and not my design</detailfield2> 
      </detail> 
      <detail> 
       <keymatch>1232</keymatch> 
       <detailfield0>Line4</detailfield0> 
       <detailfield1>this is bad structure</detailfield1> 
       <detailfield2>and not my design</detailfield2> 
      </detail> 
      <detail> 
       <keymatch>1232</keymatch> 
       <detailfield0>Line5</detailfield0> 
       <detailfield1>this is bad structure</detailfield1> 
       <detailfield2>and not my design</detailfield2> 
      </detail> 
    </header> 
</report> 

Правда, я не знаю много о XSLT, но я быстро изучаю, и я понял, что это инструмент, который мне нужно использовать. Для чего это стоит, это JD Edwards 9.1, и я буду использовать BI Publisher для отправки данных через шаблон XSL для дальнейшей передачи обслуживания партнеру EDI.

Спасибо,

Джастин

+2

Это группирование вопрос. Точный ответ зависит от того, использует ли ваш процессор XSLT 1.0 или 2.0. И это, вероятно, самый часто задаваемый вопрос здесь - так что ищите его. –

+0

Майкл, я пробовал его. И ни в одном из результатов я не нашел случая, когда данные структурированы таким образом, но для меня это все еще чужая тема. Система использует XSLT 2.0. Большое спасибо за вашу проницательную помощь. –

ответ

0

Попробуйте так:

XSLT 2,0

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

<xsl:template match="/report"> 
    <xsl:copy> 
     <xsl:for-each-group select="detail" group-starting-with="detail[header]"> 
      <header> 
       <xsl:copy-of select="header/*"/> 
       <xsl:apply-templates select="current-group()"/> 
      </header> 
     </xsl:for-each-group> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="detail"> 
    <xsl:copy> 
     <xsl:copy-of select="* except header"/> 
    </xsl:copy> 
</xsl:template> 

</xsl:stylesheet> 
+0

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