2016-03-16 2 views
0

Я следующий документ XML:Сравните и удалить дубликаты из XML с помощью XSLT

<root> 
<Organization> 
    <Organization_ID >111111</Organization_ID> 
    <Organization_Code>ABC</Organization_Code> 
</Organization> 
<Organization> 
    <Organization_ID >111111</Organization_ID> 
    <Organization_Code>ABC</Organization_Code> 
</Organization> 
<Organization> 
    <Organization_ID >111111</Organization_ID> 
    <Organization_Code>ABCD</Organization_Code> 
    <Organization_Type>Test</Organization_Type> 
</Organization> 

</root> 

мне нужен выход, как (удаление дубликатов записей):

<root> 

<Organization> 
    <Organization_ID>111111</Organization_ID> 
    <Organization_Code>ABC</Organization_Code> 
</Organization> 
<Organization> 
    <Organization_ID>111111</Organization_ID> 
    <Organization_Code>ABCD</Organization_Code> 
    <Organization_Type>Test</Organization_Type> 
</Organization> 

</root> 

Я уже написал код, ниже которого может это сделать. Мои проблемы заключаются в том, что нам нужно сравнить все дочерние элементы, как увидеть, являются ли они точными дубликатами. Как только я поставил условие Organization_Type, выход выбирает все три записи

Мой код:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/> 

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

<xsl:template match="Organization"> 
    <xsl:if 
     test=" 
      (not(following::Organization[Organization_ID = current()/Organization_ID]) 
      or not(following::Organization[Organization_Code = current()/Organization_Code]) 


      )"> 
     <xsl:copy> 

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

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

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/> 

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

<xsl:template match="Organization"> 
    <xsl:if 
     test=" 
      (not(following::Organization[Organization_ID = current()/Organization_ID]) 
      or not(following::Organization[Organization_Code = current()/Organization_Code]) 
      or not(following::Organization[Organization_Type = current()/Organization_Type]) 

      )"> 
     <xsl:copy> 

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

Любая помощь будет быть оцененным. Извините, это мой первый пост, поэтому возможно, вы не разместите его в правильном месте или в правильном формате.

+0

У меня вопрос: Вы хотите, чтобы отфильтровать точные дубликаты (все дочерние узлы должны быть одинаковыми для организации, чтобы отфильтровать) или частичные дубликаты (один дочерний узел должен быть идентичны для организации, которая будет отфильтрована)? –

+0

Да, я отфильтровываю точные дубликаты. Решение, приведенное ниже, работало для меня. Благодаря! – Sunny

ответ

1

В вашей таблице стилей показана версия 2.0, поэтому, если вы действительно используете процесс XSLT 2.0, вы можете использовать здесь xsl:for-each-group. Эффективно вы группируете конкатенацию Organization_ID, Organization_Code и Organization_Type, но выводите только первый элемент в каждой группе, тем самым удаляя дубликаты.

Попробуйте XSLT

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

    <xsl:template match="root"> 
     <xsl:copy> 
      <xsl:for-each-group select="Organization" group-by="concat(Organization_ID, '|', Organization_Code, '|', Organization_Type)"> 
       <xsl:apply-templates select="." /> 
      </xsl:for-each-group> 
     </xsl:copy> 
    </xsl:template> 

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

Спасибо большое Тим. Это сработало! – Sunny

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