2013-06-13 2 views
0

Я новичок в xslt и пробую разные варианты с нескольких дней. Am вид из идей, застрявших с ниже сценария (больше из-за моего отсутствия знаний о XSLT)Объединить 2 смежных элемента в 1 с помощью xslt

Входной XML является чем-то вроде:

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<MAIN> 
    <ProcessResponse> 
     <ORDERNO>workorder123</ORDERNO> 
     <NAME>BD-OC 102</NAME> 
     <FID>124</FID> 
     <FNO>57</FNO>  
     <AID>126</AID> 
     <BID>125</BID> 

    </ProcessResponse> 
    <ProcessResponse> 
     <ORDERNO>workorder123</ORDERNO> 
     <NAME>BD-OC 102</NAME> 
     <FID>125</FID> 
     <FNO>58</FNO> 
     <AID>127</AID> 
     <BID>128</BID> 

    </ProcessResponse> 
    <ProcessResponse> 
     <ORDERNO>workorder124</ORDERNO> 
     <NAME>BD-OC 102</NAME> 
     <FID>130</FID> 
     <FNO>59</FNO>  
     <AID>132</AID> 
     <BID>131</BID> 

    </ProcessResponse> 
    <ProcessResponse> 
     <ORDERNO>workorder124</ORDERNO> 
     <NAME>BD-OC 102</NAME> 
     <FID>132</FID> 
     <FNO>60</FNO> 
     <AID>133</AID> 
     <BID>134</BID> 

    </ProcessResponse> 

</MAIN> 

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

Выход после трансформации:

<Response> 
    <Process> 
     <ORDERNO>workorder123</ORDERNO> 
     <NAME>BD-OC 102</NAME> 

     <F1> 
      <FID>124</FID> 
      <FNO>57</FNO>  
      <AID>126</AID> 
      <BID>125</BID> 
     </F1> 

     <F2> 
      <FID>125</FID> 
      <FNO>58</FNO> 
      <AID>127</AID> 
      <BID>128</BID> 
     </F2> 

    </Process> 

    <Process> 
     <ORDERNO>workorder124</ORDERNO> 
     <NAME>BD-OC 102</NAME> 
     <F1> 
      <FID>130</FID> 
      <FNO>59</FNO>  
      <AID>132</AID> 
      <BID>131</BID> 
     </F1> 
     <F2> 
      <FID>132</FID> 
      <FNO>60</FNO> 
      <AID>133</AID> 
      <BID>134</BID> 
     </F2> 

    </Process> 


</Response> 

Примечание: Фактические файлы гораздо более сложным, чем это, но основная идея та же, слияние каждые 2 последовательных блоков в один (общая часть).

Любая помощь/руководство/указатели оценили.

+0

Какие Версия xslt? И каково правило слияния? Действительно последовательный или более, потому что ORDERNO - это то же самое? –

+0

xslt version 1.0 Правило: Каждые 2 последовательных (да, потому что orderno одинаково), на данный момент последовательные элементы (только 2) будут иметь одинаковый порядок. (Хотя я думаю, что делать это на основе orderno было бы более общим), но это было бы больше, чем то, что я ищу (не то, что еще хуже). – user1933888

ответ

0

К "объедините 2 последовательных строк", попробуйте следующее:

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

    <xsl:key name="kOrderno" match="ProcessResponse" use="ORDERNO" /> 
    <xsl:template match="@* | node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@* | node()" > 
       <xsl:with-param name="ch" select="h1" /> 
      </xsl:apply-templates> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="ProcessResponse/ORDERNO"/> 
    <xsl:template match="ProcessResponse/NAME"/> 
    <xsl:template match="ProcessResponse/text()"/> 

    <xsl:template match="/*"> 
     <Response> 
      <xsl:for-each select="ProcessResponse"> 
       <xsl:if test="position() mod 2 = 1"> 
       <Process> 
        <xsl:copy-of select="ORDERNO"/> 
        <xsl:copy-of select="NAME"/> 
        <xsl:variable name="on" select="ORDERNO" /> 
        <xsl:element name="F1"> 
         <xsl:apply-templates /> 
        </xsl:element> 
        <xsl:element name="F2"> 
         <xsl:apply-templates select="following-sibling::ProcessResponse[1]/*" /> 
        </xsl:element> 
       </Process> 
       </xsl:if> 
      </xsl:for-each> 
     </Response> 
    </xsl:template> 
</xsl:stylesheet> 
+0

Большое спасибо, он работал как шарм. Понятие, которое я взял из вашего ответа, было «position() mod 2 = 1» и «следующий брат», dint знал о них, вы спасли мои усилия в выходные. – user1933888

1

Попробуйте этот ключ на основе решения Using Keys to Group: The Muenchian Method:

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

    <xsl:key name="kOrderno" match="ProcessResponse" use="ORDERNO" /> 
    <xsl:template match="@* | node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@* | node()" > 
       <xsl:with-param name="ch" select="h1" /> 
      </xsl:apply-templates> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="ProcessResponse/ORDERNO"/> 
    <xsl:template match="ProcessResponse/NAME"/> 

    <xsl:template match="/*"> 
     <Response> 
      <xsl:for-each select="ProcessResponse[count(. | key('kOrderno', ORDERNO)[1]) =1] "> 
       <Process> 
        <xsl:copy-of select="ORDERNO"/> 
        <xsl:copy-of select="NAME"/> 
        <xsl:variable name="on" select="ORDERNO" /> 
        <xsl:for-each select=" key('kOrderno', $on)" > 
         <xsl:element name="F{position()}"> 
          <xsl:apply-templates ></xsl:apply-templates> 
         </xsl:element> 
        </xsl:for-each> 
       </Process> 
      </xsl:for-each> 
     </Response> 
    </xsl:template> 
</xsl:stylesheet> 

, который будет генерировать следующий вывод:

<?xml version="1.0"?> 
<Response> 
    <Process> 
    <ORDERNO>workorder123</ORDERNO> 
    <NAME>BD-OC 102</NAME> 
    <F1> 


       <FID>124</FID> 
       <FNO>57</FNO> 
       <AID>126</AID> 
       <BID>125</BID> 

     </F1> 
    <F2> 


       <FID>125</FID> 
       <FNO>58</FNO> 
       <AID>127</AID> 
       <BID>128</BID> 

     </F2> 
    </Process> 
    <Process> 
    <ORDERNO>workorder124</ORDERNO> 
    <NAME>BD-OC 102</NAME> 
    <F1> 


       <FID>130</FID> 
       <FNO>59</FNO> 
       <AID>132</AID> 
       <BID>131</BID> 

     </F1> 
    <F2> 


       <FID>132</FID> 
       <FNO>60</FNO> 
       <AID>133</AID> 
       <BID>134</BID> 
     </F2> 
    </Process> 
</Response> 
+0

Очень благодарен за ответ, я даже знал, что есть так много для xslt (я живу в java хорошо, что очень кстати). Но, вы полагаетесь на orderNo, чтобы сгруппировать элементы. Мой фактический xml намного сложнее с примерно 8 полями, которые являются общими (не разделяя xml, потому что это может быть пристойность). Так что лучше всего объединить две последовательные строки (xml, которые я делаю, из строк db тоже, как упоминалось в методе «MUENCHIAN». – user1933888

+0

Funy, как я мог интерпретировать ваш комментарий: «* (Хотя я предполагаю, что это делается на основе orderno был бы более общим), но это было бы больше, чем то, что я ищу (не то, что больше не плохо). * «Эта группировка по orderno может быть тем, что вы ищете. Поэтому orderno не уникален только для двух Элементы? –

+0

Да, мой плохой, смысл здесь в том, что xml имеет около 8 элементов, комбинация которых уникальна. Я создал над dummy xml, чтобы имитировать подобное условие. правдоподобное решение Я мог подумать о слиянии двух последовательных (поскольку запрос из db, который затем преобразуется в xml, всегда возвращает только 2 записи с несколькими общими (orderno, abc, xyz, message и т. д.). Извините за двусмысленность в моих комментариях. И я хотел поддержать ваш ответ, но это не позволяет говорить, что мне нужно 15 повторений. Ваш ответ потрясающий, но в настоящее время он не работает для меня. – user1933888

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