XSLT Merging two nodes into one -


i'm looking merge 2 nodes (or more) one. i've worked xslt little while, doing pretty simple stuff. i've done searching, solutions have been on head haven't been able adapt own problem. closest thing i've found answer martin honnen using function built called "eliminate-deep-equal-duplicates".

my problem can have 2 or more <coverage> nodes have "coveragecd=addrl" , need combine these nodes only, no other coverage nodes other coveragecd values. want merge addrl nodes keep unique "addr" child node addrl iterations.

one other caveat need have count of merged addrl nodes , place in "optionvalue" element. in example have 2 addrl coverage nodes optionvalue needs 2. xslt gives me need, duplicates miscparty/generalpartyinfo don't want. , while have variable addrlcount gives me correct value place in optionvalue,

i'm not quite sure how incorporate current xslt. know main problem i'm not sure "eliminate-deep-equal-duplicates" function doing. provide appreciated.

input xml

<acord>     <insurancesvcrq>         <homepolicyquoteinqrq>             <homelinebusiness>                 <dwell locationref="000b3c6b-264f-83b7-1b80-006a3ce1f40e">       <policytypecd>06</policytypecd>       <purchasedt>2011-05-10</purchasedt>       <construction>         <constructioncd>f</constructioncd>         <com.ormutual_recontype>standard</com.ormutual_recontype>         <yearbuilt>1988</yearbuilt>         <bldgarea>           <numunits>1200</numunits>           <unitmeasurementcd>square foot</unitmeasurementcd>         </bldgarea>       </construction>                     <coverage>                         <coveragecd>medpm</coveragecd>                         <limit>                             <formatinteger>1000</formatinteger>                         </limit>                     </coverage>                     <coverage>                         <coveragecd>lac</coveragecd>                         <limit>                             <formatinteger>50000</formatinteger>                         </limit>                     </coverage>                     <coverage>                         <coveragecd>addrl</coveragecd>                         <option>                             <optiontypecd>num1</optiontypecd>                             <optionvalue>1</optionvalue>                         </option>                         <miscparty>                             <generalpartyinfo>                                 <addr>                                     <addrtypecd>streetaddress</addrtypecd>                                     <addr1>9325 sw camille ter</addr1>                                     <city>portland</city>                                     <stateprovcd>or</stateprovcd>                                     <postalcode>97223</postalcode>                                     <county>washington</county>                                 </addr>                             </generalpartyinfo>                         </miscparty>                     </coverage>                     <coverage>                         <coveragecd>addrl</coveragecd>                         <option>                             <optiontypecd>num1</optiontypecd>                             <optionvalue>1</optionvalue>                         </option>                         <miscparty>                             <generalpartyinfo>                                 <addr>                                     <addrtypecd>streetaddress</addrtypecd>                                     <addr1>2222 andrew ave nw</addr1>                                     <city>salem</city>                                     <stateprovcd>or</stateprovcd>                                     <postalcode>97304</postalcode>                                     <county>polk</county>                                 </addr>                             </generalpartyinfo>                         </miscparty>                     </coverage>                 </dwell>             </homelinebusiness>         </homepolicyquoteinqrq>     </insurancesvcrq> </acord> 

desired output

<acord>     <insurancesvcrq>         <homepolicyquoteinqrq>             <homelinebusiness>                 <dwell locationref="000b3c6b-264f-83b7-1b80-006a3ce1f40e">       <policytypecd>06</policytypecd>       <purchasedt>2011-05-10</purchasedt>       <construction>         <constructioncd>f</constructioncd>         <com.ormutual_recontype>standard</com.ormutual_recontype>         <yearbuilt>1988</yearbuilt>         <bldgarea>           <numunits>1200</numunits>           <unitmeasurementcd>square foot</unitmeasurementcd>         </bldgarea>       </construction>                     <coverage>                         <coveragecd>medpm</coveragecd>                         <limit>                             <formatinteger>1000</formatinteger>                         </limit>                     </coverage>                     <coverage>                         <coveragecd>lac</coveragecd>                         <limit>                             <formatinteger>50000</formatinteger>                         </limit>                     </coverage>                     <coverage>                         <coveragecd>addrl</coveragecd>                         <option>                             <optiontypecd>num1</optiontypecd>                             <optionvalue>2</optionvalue>                         </option>                         <miscparty>                             <generalpartyinfo>                                 <addr>                                     <addrtypecd>streetaddress</addrtypecd>                                     <addr1>9325 sw camille ter</addr1>                                     <city>portland</city>                                     <stateprovcd>or</stateprovcd>                                     <postalcode>97223</postalcode>                                     <county>washington</county>                                 </addr>                                 <addr>                                     <addrtypecd>streetaddress</addrtypecd>                                     <addr1>2222 andrew ave nw</addr1>                                     <city>salem</city>                                     <stateprovcd>or</stateprovcd>                                     <postalcode>97304</postalcode>                                     <county>polk</county>                                 </addr>                             </generalpartyinfo>                         </miscparty>                     </coverage>                 </dwell>             </homelinebusiness>         </homepolicyquoteinqrq>     </insurancesvcrq> </acord> 

my attempt @ xslt

<?xml version="1.0"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform" xmlns:xs="http://www.w3.org/2001/xmlschema" xmlns:functx="http://www.functx.com" xmlns:mf="http://example.com/mf" exclude-result-prefixes="xs functx mf">     <xsl:output indent="yes" method="xml" omit-xml-declaration="yes"/>      <xsl:function name="functx:index-of-node" as="xs:integer*">         <xsl:param name="nodes" as="node()*"/>         <xsl:param name="nodetofind" as="node()"/>          <xsl:sequence select="   $seq in (1 count($nodes))   return $seq[$nodes[$seq] $nodetofind]  "/>     </xsl:function>      <xsl:function name="mf:eliminate-deep-equal-duplicates" as="node()*">         <xsl:param name="nodes"/>         <xsl:sequence select="for $node in $nodes             return $node[not(some $preceding-node in $nodes[position() lt functx:index-of-node($nodes, $node)] satisfies deep-equal($node, $preceding-node))]"/>     </xsl:function>      <xsl:template match="@*|node()">         <xsl:copy>             <xsl:apply-templates select="@*|node()"/>         </xsl:copy>     </xsl:template>      <xsl:variable name="addrlcount" select="count(acord/insurancesvcrq/homepolicyquoteinqrq/homelinebusiness/dwell/coverage[./coveragecd='addrl'])"/>     <xsl:template match="acord/insurancesvcrq/homepolicyquoteinqrq/homelinebusiness/dwell">         <xsl:copy>             <xsl:for-each-group select="coverage" group-by="coveragecd">                 <xsl:copy>                     <xsl:apply-templates select="coverage[./coveragecd='addrl'],                      mf:eliminate-deep-equal-duplicates(current-group()/(* except (addr))),                      addr"/>                 </xsl:copy>             </xsl:for-each-group>         </xsl:copy>     </xsl:template> </xsl:stylesheet> 

you grouping coverage elements coveragecd values

<xsl:for-each-group select="coverage" group-by="coveragecd"> 

so, @ point positioned on coverage element (ones first occurrence of coveragecd value). this...

<xsl:apply-templates select="coverage[./coveragecd='addrl'], 

this means looking coverage element child of covering coverage element, return element. similarly, this....

mf:eliminate-deep-equal-duplicates(current-group()/(* except (addr))) 

current-group() returns coverage elements same code, none of have addr elements, selects elements.

what can possibly do, replace statement this:

<xsl:apply-templates select="mf:eliminate-deep-equal-duplicates(current-group()/*)" /> 

then can have templates matching elements wish change.

try xslt:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform" xmlns:xs="http://www.w3.org/2001/xmlschema" xmlns:functx="http://www.functx.com" xmlns:mf="http://example.com/mf" exclude-result-prefixes="xs functx mf">     <xsl:output indent="yes" method="xml" omit-xml-declaration="yes"/>      <xsl:function name="functx:index-of-node" as="xs:integer*">         <xsl:param name="nodes" as="node()*"/>         <xsl:param name="nodetofind" as="node()"/>          <xsl:sequence select="   $seq in (1 count($nodes))   return $seq[$nodes[$seq] $nodetofind]  "/>     </xsl:function>      <xsl:function name="mf:eliminate-deep-equal-duplicates" as="node()*">         <xsl:param name="nodes"/>         <xsl:sequence select="for $node in $nodes             return $node[not(some $preceding-node in $nodes[position() lt functx:index-of-node($nodes, $node)] satisfies deep-equal($node, $preceding-node))]"/>     </xsl:function>      <xsl:template match="@*|node()">         <xsl:copy>             <xsl:apply-templates select="@*|node()"/>         </xsl:copy>     </xsl:template>      <xsl:template match="acord/insurancesvcrq/homepolicyquoteinqrq/homelinebusiness/dwell">         <xsl:copy>             <xsl:apply-templates select="@*|node() except coverage" />             <xsl:for-each-group select="coverage" group-by="coveragecd">                 <xsl:copy>                     <xsl:apply-templates select="mf:eliminate-deep-equal-duplicates(current-group()/*)" />                 </xsl:copy>             </xsl:for-each-group>         </xsl:copy>     </xsl:template>      <xsl:template match="optionvalue">         <xsl:copy>             <xsl:value-of select="count(mf:eliminate-deep-equal-duplicates(current-group()/miscparty/generalpartyinfo/addr))" />         </xsl:copy>     </xsl:template>      <xsl:template match="generalpartyinfo">         <xsl:copy>             <xsl:apply-templates select="mf:eliminate-deep-equal-duplicates(current-group()/miscparty/generalpartyinfo/addr)" />         </xsl:copy>     </xsl:template> </xsl:stylesheet> 

to honest, don't think need mf:eliminate-deep-equal-duplicates in particular case. xslt produces result need

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform" xmlns:xs="http://www.w3.org/2001/xmlschema" xmlns:functx="http://www.functx.com" xmlns:mf="http://example.com/mf" exclude-result-prefixes="xs functx mf">     <xsl:output indent="yes" method="xml" omit-xml-declaration="yes"/>      <xsl:template match="@*|node()">         <xsl:copy>             <xsl:apply-templates select="@*|node()"/>         </xsl:copy>     </xsl:template>      <xsl:template match="acord/insurancesvcrq/homepolicyquoteinqrq/homelinebusiness/dwell">         <xsl:copy>             <xsl:apply-templates select="@*|node() except coverage" />             <xsl:for-each-group select="coverage" group-by="coveragecd">                 <xsl:copy>                     <xsl:apply-templates  />                 </xsl:copy>             </xsl:for-each-group>         </xsl:copy>     </xsl:template>      <xsl:template match="optionvalue">         <xsl:copy>             <xsl:value-of select="count(current-group()/miscparty/generalpartyinfo/addr)" />         </xsl:copy>     </xsl:template>      <xsl:template match="generalpartyinfo">         <xsl:copy>             <xsl:apply-templates select="current-group()/miscparty/generalpartyinfo/addr" />         </xsl:copy>     </xsl:template> </xsl:stylesheet> 

Comments

Popular posts from this blog

javascript - jQuery: Add class depending on URL in the best way -

caching - How to check if a url path exists in the service worker cache -

Redirect to a HTTPS version using .htaccess -