2012-04-29 2 views
1

Это входной файл:Объединение двух или более XML-узел с помощью XSLT

<root> 
    <node id="N1"> 
     <fruit id="1" action="aaa"> 
      <orange id="x" action="create"> 
       <attribute> 
        <color>Orange</color> 
        <year>2012</year> 
       </attribute> 
      </orange> 
      <orange id="x" action="change"> 
       <attribute> 
        <color>Red</color> 
       </attribute> 
      </orange> 
      <orange id="x" action="change"> 
       <attribute> 
        <color>Blue</color> 
        <condition>good</condition> 
       </attribute> 
      </orange> 
     </fruit> 

    </node> 

    <node id="N2"> 
     <car id="1">  
      <bmw id="i" action="change"> 
       <attribute> 
        <color>Blue</color>  
       </attribute> 
      </bmw>  
      <bmw id="i" action="change"> 
       <attribute> 
        <color>Yellow</color>  
       </attribute> 
      </bmw> 
      <bmw id="i" action="change"> 
       <attribute> 
        <color>Pink</color>  
       </attribute> 
      </bmw> 


     <bmw id="j" action="delete"> 
      <attribute> 
       <color>Blue</color>  
      </attribute> 
     </bmw> 
     <bmw id="j" action="delete"> 
      <attribute> 
       <color>Yellow</color>  
      </attribute> 
     </bmw> 

    </car> 
    </node> 
</root> 

Это ожидаемый результат:

<root> 
    <node id="N1"> 
     <fruit id="1" action="aaa"> 
      <orange id="x" action="create"> 
       <attribute> 
        <color>Blue</color> 
        <year>2012</year> 
        <condition>good</condition> 
       </attribute> 
      </orange>      
     </fruit>  
    </node> 

    <node id="N2"> 
     <car id="1">  

      <bmw id="i" action="change"> 
       <attribute> 
        <color>Pink</color>  
       </attribute> 
      </bmw> 


     <bmw id="j" action="delete"> 
      <attribute> 
       <color>Yellow</color>  
      </attribute> 
     </bmw> 
     </car> 
    </node> 
</root> 

Правило:

  1. если есть узел с методом 'create', за которым следует один или несколько методов 'change', мы объединяем их вместе и используем ВСЕ дочерние элементы из последнего «изменения» в узел с «create», метод. (Примечание: хорошо добавляется)

  2. Если есть один или несколько методов «смены», мы объединяем их и используем только детей из последнего метода «изменения».

  3. Если есть один или несколько методов 'delete', мы объединяем их и используем только дети из последнего метода 'delete'.

Обратите внимание, что идентификатор должен быть одинаковым для узла, подлежащего объединению.

Пожалуйста, сообщите мне об этом решении XSLT. Большое спасибо.

Уважения, Джон

ответ

2

Это преобразование:

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="node()|@*"> 
     <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="node/*/*[1]"> 
     <xsl:copy> 
     <xsl:apply-templates select="@* | ../*[last()]/*"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match= 
     "node/*/* 
     [@action='delete' 
     and 
     following-sibling::*[1][@action='delete'] 
     ]"/> 

    <xsl:template match= 
     "node/*/* 
     [@action='change' 
     and 
     following-sibling::*[1][@action='change'] 
     or 
     preceding-sibling::*[@action='create'] 
     ]"/> 
</xsl:stylesheet> 

при нанесении на предоставленном документе XML:

<root> 
    <node id="N1"> 
     <fruit id="1" action="aaa"> 
      <orange id="x" action="create"> 
       <attribute> 
        <color>Orange</color> 
       </attribute> 
      </orange> 
      <orange id="x" action="change"> 
       <attribute> 
        <color>Red</color> 
       </attribute> 
      </orange> 
      <orange id="x" action="change"> 
       <attribute> 
        <color>Blue</color> 
        <condition>good</condition> 
       </attribute> 
      </orange> 
     </fruit> 
    </node> 
    <node id="N2"> 
     <car id="1"> 
      <bmw id="i" action="change"> 
       <attribute> 
        <color>Blue</color> 
       </attribute> 
      </bmw> 
      <bmw id="i" action="change"> 
       <attribute> 
        <color>Yellow</color> 
       </attribute> 
      </bmw> 
      <bmw id="i" action="change"> 
       <attribute> 
        <color>Pink</color> 
       </attribute> 
      </bmw> 
      <bmw id="j" action="delete"> 
       <attribute> 
        <color>Blue</color> 
       </attribute> 
      </bmw> 
      <bmw id="j" action="delete"> 
       <attribute> 
        <color>Yellow</color> 
       </attribute> 
      </bmw> 
     </car> 
    </node> 
</root> 

производит разыскиваемый, правильный результат:

<root> 
    <node id="N1"> 
     <fruit id="1" action="aaa"> 
     <orange id="x" action="create"> 
      <attribute> 
       <color>Blue</color> 
       <condition>good</condition> 
      </attribute> 
     </orange> 
     </fruit> 
    </node> 
    <node id="N2"> 
     <car id="1"> 
     <bmw id="i" action="change"> 
      <attribute> 
       <color>Pink</color> 
      </attribute> 
     </bmw> 
     <bmw id="j" action="delete"> 
      <attribute> 
       <color>Yellow</color> 
      </attribute> 
     </bmw> 
     </car> 
    </node> 
</root> 
+0

спасибо так много .. – John

+1

не уверен, что вы должны были учтены в этом случае, но если последние два 'bmw's где' create' сопровождаемых 'change' преобразования будет использовать' create' узел со своими дочерними элементами. Было бы легко исправить перенос этих двух «осиротевших» узлов «bmw» в родительский «автомобиль», как и другие, но не уверен, сколько контроля над входным файлом. –

+0

@DimitreNovatchev Привет, извините, вы могли бы внести небольшое обновление в решения. Потому что должен быть внизу. Также я случайно помещаю неправильное имя метода. Он должен только «изменять» не изменять. Спасибо. – John

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