2013-09-24 7 views
1

Я ищу способ:Merge аналогичных узлов и удалить дубликаты

  1. слияние узлов, чьи имена и значения аналогичны.
  2. после слияния удалите повторяющиеся атрибуты узла.
  3. Если два атрибута имеют разные значения, значение первого атрибута должно заменить значением второго атрибута, который был объединен.

Вот пример кода:

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<books> 
    <mbean code="abc.def.ghi" name="com.booking.props:name=abcdefgh"> 
     <attribute name="BName">abc123</attribute> 
     <depends optional-attribute-name="Bookname">mypersonnelbook</depends> 
     <attribute name="Type1">book.type1.name</attribute> 
     <attribute name="Properties"> 
      bookname=book1 
      price=100 
     </attribute> 
    </mbean> 
    <mbean code="abc.def.ghi" name="com.booking.props:name=abcdefgh"> 
     <attribute name="BName">abc123</attribute> 
     <depends optional-attribute-name="Bookname">mypersonnelbook</depends> 
     <attribute name="Type2">book.type2.name</attribute>   
     <attribute name="Properties"> 
      bookname=book1 
      price=100 
     </attribute> 
    </mbean> 
    <us-country-factory> 
     <jndi-name>books/props/Classic</jndi-name> 
     <file-name>book1</file-name> 
     <state-location>central.wharehouse</state-location> 
     <store-property name="store" type="java.lang.String">abc</store-property> 
     <store-property name="storetype" type="java.lang.String">1223</store-property> 
     <store-property name="storelocation" type="java.lang.String">defsdgfd</store-property> 
     <store-property name="storecategory" type="java.lang.String">hjtbngb</store-property> 
    </us-country-factory> 
    <us-country-factory> 
     <jndi-name>books/props/Classic</jndi-name> 
     <file-name>book1</file-name> 
     <state-location>central.wharehouse</state-location> 
     <store-property name="store" type="java.lang.String">defghij</store-property> 
     <store-property name="storetype" type="java.lang.String">1223</store-property> 
     <store-property name="storelocation" type="java.lang.String">32das</store-property> 
     <store-property name="storecategory" type="java.lang.String">hjtbngb</store-property> 
     <store-property name="storeratings" type="java.lang.String">5</store-property> 

Выходной Ищу является:

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<books> 
    <mbean code="abc.def.ghi" name="com.booking.props:name=abcdefgh"> 
     <attribute name="BName">abc123</attribute> 
     <depends optional-attribute-name="Bookname">mypersonnelbook</depends> 
     <attribute name="Type1">book.type1.name</attribute> 
     <attribute name="Type2">book.type2.name</attribute> 
     <attribute name="Properties"> 
      bookname=book1 
      price=100 
     </attribute> 
    </mbean> 
    <us-country-factory> 
     <jndi-name>books/props/Classic</jndi-name> 
     <file-name>book1</file-name> 
     <state-location>central.wharehouse</state-location> 
     <store-property name="store" type="java.lang.String">defghij</store-property> 
     <store-property name="storetype" type="java.lang.String">1223</store-property> 
     <store-property name="storelocation" type="java.lang.String">32das</store-property> 
     <store-property name="storecategory" type="java.lang.String">hjtbngb</store-property> 
     <store-property name="storeratings" type="java.lang.String">5</store-property> 
    </us-country-factory> 
</books> 

     </us-country-factory> 
    </books> 

Это файл XSL, что я пробовал:

<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:key name="mbeanName" match="//mbean/@name" use="."/> 
    <xsl:key name="mbeanCount" match="//mbean[generate-id(@name) = generate-id(key('mbeanName', @name)[1])]" use="count(.)"/> 
    <xsl:key name="us-country-factoryName" match="//us-country-factory[jndi-name/text()]" use="."/> 
    <xsl:key name="us-country-factoryCount" match="/us-country-factory[generate-id(jndi-name/text()) = generate-id(key('us-country-factoryName', jndi-name/text())[1])]" use="count(.)"/> 

<xsl:template match="node()|@*"> 
     <xsl:copy> 
      <xsl:apply-templates select="node()|@*"/> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template match="mbean[count(. | key('mbeanCount', /mbean/@name))]" /> 
    <xsl:template match="mbean[count(. | key('us-country-factoryCount', us-country-factory[jndi-name/text()]))]" /> 
</xsl:stylesheet> 
+0

Любые предложения приветствуются. – phani

ответ

1

Как вы отметили вопрос как XSLT 2.0, я бы предложил попытаться использовать for-each-group вместо клавиш. Вот пример таблицы стилей:

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

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

<xsl:template match="books"> 
    <xsl:copy> 
    <xsl:for-each-group select="mbean" group-by="@name"> 
     <xsl:copy> 
     <xsl:copy-of select="@*"/> 
     <xsl:for-each-group select="current-group()/*" group-by="node-name(.)"> 
      <xsl:for-each-group select="current-group()" group-by="@*"> 
      <xsl:copy> 
       <xsl:copy-of select="@*, current-group()[last()]/node()"/> 
      </xsl:copy> 
      </xsl:for-each-group> 
     </xsl:for-each-group> 
     </xsl:copy> 
    </xsl:for-each-group> 
    <xsl:for-each-group select="us-country-factory" group-by="jndi-name"> 
     <xsl:copy> 
     <xsl:copy-of select="@*, *[not(@*)]"/> 
     <xsl:for-each-group select="current-group()/*[@*]" group-by="string-join(@*, '|')"> 
      <xsl:copy> 
      <xsl:copy-of select="@*, current-group()[last()]/node()"/> 
      </xsl:copy> 
     </xsl:for-each-group> 
     </xsl:copy> 
    </xsl:for-each-group> 
    </xsl:copy> 
</xsl:template> 

</xsl:stylesheet> 

Это превращает

<books> 
    <mbean code="abc.def.ghi" name="com.booking.props:name=abcdefgh"> 
     <attribute name="BName">abc123</attribute> 
     <depends optional-attribute-name="Bookname">mypersonnelbook</depends> 
     <attribute name="Type1">book.type1.name</attribute> 
     <attribute name="Properties"> 
      bookname=book1 
      price=100 
     </attribute> 
    </mbean> 
    <mbean code="abc.def.ghi" name="com.booking.props:name=abcdefgh"> 
     <attribute name="BName">abc123</attribute> 
     <depends optional-attribute-name="Bookname">mypersonnelbook</depends> 
     <attribute name="Type2">book.type2.name</attribute>   
     <attribute name="Properties"> 
      bookname=book1 
      price=100 
     </attribute> 
    </mbean> 
    <us-country-factory> 
     <jndi-name>books/props/Classic</jndi-name> 
     <file-name>book1</file-name> 
     <state-location>central.wharehouse</state-location> 
     <store-property name="store" type="java.lang.String">abc</store-property> 
     <store-property name="storetype" type="java.lang.String">1223</store-property> 
     <store-property name="storelocation" type="java.lang.String">defsdgfd</store-property> 
     <store-property name="storecategory" type="java.lang.String">hjtbngb</store-property> 
    </us-country-factory> 
    <us-country-factory> 
     <jndi-name>books/props/Classic</jndi-name> 
     <file-name>book1</file-name> 
     <state-location>central.wharehouse</state-location> 
     <store-property name="store" type="java.lang.String">defghij</store-property> 
     <store-property name="storetype" type="java.lang.String">1223</store-property> 
     <store-property name="storelocation" type="java.lang.String">32das</store-property> 
     <store-property name="storecategory" type="java.lang.String">hjtbngb</store-property> 
     <store-property name="storeratings" type="java.lang.String">5</store-property> 
    </us-country-factory> 
</books> 

в

<books> 
    <mbean code="abc.def.ghi" name="com.booking.props:name=abcdefgh"> 
     <attribute name="BName">abc123</attribute> 
     <attribute name="Type1">book.type1.name</attribute> 
     <attribute name="Properties"> 
      bookname=book1 
      price=100 
     </attribute> 
     <attribute name="Type2">book.type2.name</attribute> 
     <depends optional-attribute-name="Bookname">mypersonnelbook</depends> 
    </mbean> 
    <us-country-factory> 
     <jndi-name>books/props/Classic</jndi-name> 
     <file-name>book1</file-name> 
     <state-location>central.wharehouse</state-location> 
     <store-property name="store" type="java.lang.String">defghij</store-property> 
     <store-property name="storetype" type="java.lang.String">1223</store-property> 
     <store-property name="storelocation" type="java.lang.String">32das</store-property> 
     <store-property name="storecategory" type="java.lang.String">hjtbngb</store-property> 
     <store-property name="storeratings" type="java.lang.String">5</store-property> 
    </us-country-factory> 
</books> 

Я понимаю, что это не полное решение, но это должно дать вам представление о том, как вы могли бы подойти проблема с использованием XSLT 2.0. Вы просто определите, что именно «объединить узлы, имена или значения которых похожи» означает для ваших разных типов элементов, а затем реализовать это, используя для каждой группы.

Вот некоторые попытки объяснения, код

<xsl:for-each-group select="mbean" group-by="@name"> 
    <xsl:copy> 
    <xsl:copy-of select="@*"/> 
    <xsl:for-each-group select="current-group()/*" group-by="node-name(.)"> 
     <xsl:for-each-group select="current-group()" group-by="@*"> 
     <xsl:copy> 
      <xsl:copy-of select="@*, current-group()[last()]/node()"/> 
     </xsl:copy> 
     </xsl:for-each-group> 
    </xsl:for-each-group> 
    </xsl:copy> 
</xsl:for-each-group> 

группирует mbean элементов их name атрибутов, а затем делает неполную копию первого элемента в группе (как вы хотите, чтобы устранить дубликаты) , затем копирует любые атрибуты. Кроме того, внутренний for-each-group группирует все дочерние элементы в группе mbean по их имени (поэтому мы группируем все элементы attribute и группируем все элементы depends), а затем по их значениям атрибутов. Это упрощение, так как вход имеет только один атрибут для этих элементов. Таким образом, внутри внутренней для каждой группы мы теперь имеем группы, например. attribute name="BName" элементов. Мы делаем мелкую копию первого элемента в группе (контекстный узел в группе), затем копируем его атрибуты, но копируем содержимое последнего элемента в группе.

+0

gr8, он работает для меня .. можете ли вы, пожалуйста, приложить дополнительные усилия и немного объяснить логику, используемую для каждой группы. – phani

+0

, которые имеют смысл, спасибо за дополнительную информацию. – phani

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