i have scoured google , stack overflow , have been unable find answer this. apologize if duplicate.
i have xml document has nested types; however, several repeating elements appear throughout document different names , parents. when compared xsd, these repeating elements found same type of object, referenced throughout. there 50 different types reference repeating element. how can write 1 template can called inside of each of 50 templates need write don't have duplicate transform each parent type?
for example:
<model1> <description>desc1</description> <code>code1</code> <type>vmo</type> <model2> <description>desc1</description> <code>code1</code> <type>vmo</type> </model2> </model1> <model3> <description>desc1</description> <code>code1</code> <type>vmo</type> <model4> <model5> <description>desc1</description> <code>code1</code> <type>vmo</type> <model6> <description>desc1</description> <code>code1</code> <type>vmo</type> </model6> </model5> <code>code1</code> <type>vmo</type> </model4> </model3> <model7> <description>desc1</description> <code>code1</code> <type>vmo</type> <model8> <description>desc1</description> <code>code1</code> <type>vmo</type> </model8> </model7>
in example above instance, model2
, model6
, model8
same structure , need apply same transform each element. this:
<xsl:template match="model1"> <xsl:copy> <!-- maps other elements --> <xsl:apply-templates select="somespecialfunction(model3)" /> </xsl:copy> </xsl:template> <xsl:template match="model5"> <xsl:copy> <!-- maps other elements --> <xsl:apply-templates select="somespecialfunction(model6)" /> </xsl:copy> </xsl:template> <xsl:template match="model7"> <xsl:copy> <!-- maps other elements --> <xsl:apply-templates select="somespecialfunction(model8)" /> </xsl:copy> </xsl:template>
and transform parent elements. possible?
i know this:
<xsl:template match="model1/model3"> <xsl:copy> <!-- transfrom type --> <xsl:apply-templates select="node()|@*" /> </xsl:copy> </xsl:template> <xsl:template match="model5/model6"> <xsl:copy> <!-- transfrom type --> <xsl:apply-templates select="node()|@*" /> </xsl:copy> </xsl:template> <xsl:template match="model7/model8"> <xsl:copy> <!-- transfrom type --> <xsl:apply-templates select="node()|@*" /> </xsl:copy> </xsl:template>
but repeating lot of code. advice?
edit:
i general in original post, sorry that. more concrete example (and in case, 1 of objects have) address , sub types associated them. several different types of elements have address. example, have product element has seller, supplier, re-seller, list of stakeholder each address, etc. each 1 of these addresses has different name.
<product> <seller> <businessaddress>...</businessaddress> <distributionaddress>...</distributionaddress> <maincontactaddress>...</maincontactaddress> </seller> <reseller> <businessaddress>...</businessaddress> <storemanageraddress>...</storemanageraddress> <maincontactaddress>...</maincontactaddress> </reseller> <supplier> <businessaddress>...</businessaddress> <distributioncenteraddress>...</distributioncenteraddress> <maincontactaddress>...</maincontactaddress> </supplier> <stakeholders> <entity> <homeaddress>...</homeaddress> <workaddress>...</workaddress> <secondaryaddress>...</secondaryaddress> <street>...</street> <crossstreet>...</crossstreet> </entity> </stakeholders> </product> <surveyrespondents> <surveyrespondent> <address>...</address> <business>...</business> </surveyrespondent> <surveyrespondent> <address>...</address> <business>...</business> </surveyrespondent> </surveyrespondents>
now isn't of elements have addresses, if go approaches have done before have either make list of templates (like mentioned above) or go long list of matches michael.hor257k suggested.
<xsl:template match="address | business | secondaryaddress | workaddress | home | secondaryaddress | businessaddress | ..."> <!-- apply same transform of these --> </xsl:template>
to compound problem each address made of multiple sub-types: addresscategory, district, zone, street, streettype, postdirection, predirection, etc. each 1 of these types has same structure, run problem of how match against every type. sub types, street
, string in places (when used in other elements) , "codetype" in others. if match wind ugly , not done whole document yet:
<xsl:template match="address | business | secondaryaddress | workaddress | home | secondaryaddress | businessaddress | ..."> <!-- apply same transform of these --> </xsl:template> <xsl:template match="address/street | business/street | secondaryaddress/street | workaddress/street | home/street | secondaryaddress/street | businessaddress/street | addresstype | district | zone..."> <!-- apply same transform of these --> </xsl:template>
am stuck hard read, debug, , maintain xslt of better way this?
it's difficult answer question, because it's context - , not providing full context.
in example above instance, model2, model6 , model8 same structure , need apply same transform each element
why don't do:
<xsl:template match="model2 | model6 | model8"> <!-- apply same transform of these --> </xsl:template>
note template can applied node parent of model2 and/or model6 and/or model8 (actually, can applied other contexts too, that's not point here).
how can write 1 template can called inside of each of 50 templates need write
are sure need write 50 templates?
re edit:
the alternative to:
<xsl:template match="address | business | secondaryaddress | workaddress | home | secondaryaddress | businessaddress | ..."> <!-- apply same transform of these --> </xsl:template>
would be:
<xsl:template name="address"> <xsl:param name="address-node" /> <!-- apply transform --> </xsl:template>
but have call template explicitly each location address exists, example:
<xsl:template match="seller"> <xsl:copy> <!-- other code --> <xsl:call-template name="address"> <xsl:with-param name="address-node" select="businessaddress"/> </xsl:call-template> <xsl:call-template name="address"> <xsl:with-param name="address-node" select="distributionaddress"/> </xsl:call-template> <xsl:call-template name="address"> <xsl:with-param name="address-node" select="maincontactaddress"/> </xsl:call-template> <!-- more code --> </xsl:copy> </xsl:template>
possibly, shortened to:
<xsl:template match="seller"> <xsl:copy> <!-- other code --> <xsl:call-template name="address"> <xsl:with-param name="address-nodes" select="businessaddress | distributionaddress | maincontactaddress"/> </xsl:call-template> <!-- more code --> </xsl:copy> </xsl:template>
even so, not sure alternative more attractive original suggestion.