xslt - Copying a node from a custom function -


i need remove duplicate values following xslt. 2 nodes should equal if attributes equal. solution i've come first occurrence of component name(0 preceding siblings). if there no following siblings directly copy node. if there following siblings nodes including current node in variable. process variable code below find unique occurences , copy node when found. problem copying node <xsl:copy-of> function not seem work. suggestions on how this?

xml

<component name="compa">     <group>         <field name="field1" required="y">          <field name="field2" required="n">          <field name="field3" required="y">      </group> </component> <component name="compb">     <group>         <field name="field1" required="n">          <field name="field2" required="n">          <field name="field3" required="n">      </group> </component> <component name="compa">     <group>         <field name="field1" required="n">          <field name="field2" required="n">          <field name="field3" required="n">      </group> </component> <component name="compc">     <group>         <field name="field1" required="n">          <field name="field2" required="n">          <field name="field3" required="n">      </group> </component> <component name="compa">     <group>         <field name="field1" required="n">          <field name="field2" required="n">          <field name="field4" required="n">          <field name="field7" required="n">          <field name="field10" required="n">      </group> </component> <component name="compa">     <group>         <field name="field1" required="y">          <field name="field2" required="n">          <field name="field3" required="y">      </group> </component> <component name="compa">     <group>         <field name="field1" required="n">          <field name="field2" required="n">          <field name="field3" required="n">      </group> </component> 

xsl

<xsl:template match="component">         <xsl:if test="count(preceding-sibling::*[@name=current()/@name])=0">             <xsl:if test="name(//text()/parent::*) != 'component'">              <xsl:choose>                     <xsl:when test="count(following-sibling::*[@name=current()/@name])= 0">                         <xsl:copy>                             <xsl:apply-templates select="@*|node()"/>                         </xsl:copy>                     </xsl:when>                      <xsl:when test="count(following-sibling::*[@name=current()/@name]) != 0">                         <xsl:variable name="cnt"><xsl:value-of select="count(following-sibling::*[@name=current()/@name]) + 1"/> </xsl:variable>                         <xsl:variable name="arr" select="following-sibling::*[@name=current()/@name] | current()"/>                         <xsl:value-of select="foo:f($cnt -1, $arr, $cnt)"/>                     </xsl:when>                 </xsl:choose>             </xsl:if>         </xsl:if>     </xsl:template>      <xsl:function name="foo:f">         <xsl:param name="i"/>         <xsl:param name="arr"/>         <xsl:param name="cnt"/>         <xsl:copy-of select="$arr[$i]"/>         <xsl:if test="$i != 0">             <xsl:if test="foo:g($i, $cnt - 1, $arr)">                 <xsl:comment><xsl:value-of select="$arr[$i]/node()/node()"/></xsl:comment>                 <xsl:element name="component">                     <xsl:copy-of select="$arr[1]"></xsl:copy-of>                 </xsl:element>             </xsl:if>             <xsl:value-of select="foo:f($i -1, $arr, $cnt)"/>         </xsl:if>     </xsl:function>      <xsl:function name="foo:g">         <xsl:param name="i"/>         <xsl:param name="j"/>         <xsl:param name="arr"/>         <xsl:if test="$j>0">             <xsl:value-of select="false()"/>         </xsl:if>          <xsl:if test="$arr[$i]/child::*/child::*/@name != $arr[$j]/child::*/child::*/@name">             <xsl:value-of select="foo:g($i, $j - 1, $arr)"/>             <xsl:copy-of select="$arr[$i]"/>         </xsl:if>         <xsl:if test="$i=$j">             <xsl:value-of select="true()"/>         </xsl:if>         <xsl:if test="$i!=$j">             <xsl:value-of select="false()"/>         </xsl:if>     </xsl:function> 

required output

<component name="compa1">     <group>         <field name="field1" required="y">          <field name="field2" required="n">          <field name="field3" required="y">      </group> </component> <component name="compb">     <group>         <field name="field1" required="n">          <field name="field2" required="n">          <field name="field3" required="n">      </group> </component> <component name="compa2">     <group>         <field name="field1" required="n">          <field name="field2" required="n">          <field name="field3" required="n">      </group> </component> <component name="compc">     <group>         <field name="field1" required="n">          <field name="field2" required="n">          <field name="field3" required="n">      </group> </component> <component name="compa3">     <group>         <field name="field1" required="n">          <field name="field2" required="n">          <field name="field4" required="n">          <field name="field7" required="n">          <field name="field10" required="n">      </group> </component> 

wild guess, if filter out deep-equal component elements with

<xsl:transform xmlns:xsl="http://www.w3.org/1999/xsl/transform" version="2.0">      <xsl:template match="@*|node()">         <xsl:copy>             <xsl:apply-templates select="@*|node()"/>         </xsl:copy>     </xsl:template>      <xsl:template match="component[some $sib in preceding-sibling::component satisfies deep-equal(., $sib)]"/>  </xsl:transform> 

you might want. if want number result components in name (e.g. compa1) gets more complicated:

<xsl:transform xmlns:xsl="http://www.w3.org/1999/xsl/transform" version="2.0"     xmlns:functx="http://www.functx.com"     exclude-result-prefixes="functx">      <xsl:import href="http://www.xsltfunctions.com/xsl/functx-1.0-nodoc-2007-01.xsl"/>      <xsl:template match="@*|node()">         <xsl:copy>             <xsl:apply-templates select="@*|node()"/>         </xsl:copy>     </xsl:template>      <xsl:template match="component/@name">         <xsl:variable name="group" select="../../component[@name = current()][not(some $sib in preceding-sibling::component satisfies deep-equal(., $sib))]"/>         <xsl:attribute name="{name()}" select="if ($group[2]) concat(., functx:index-of-node($group, ..)) else ."/>     </xsl:template>      <xsl:template match="component[some $sib in preceding-sibling::component satisfies deep-equal(., $sib)]"/>  </xsl:transform> 

Comments

Popular posts from this blog

php - Wordpress website dashboard page or post editor content is not showing but front end data is showing properly -

javascript - Get parameter of GET request -

javascript - Twitter Bootstrap - how to add some more margin between tooltip popup and element -