XSLT template match param containing xpaths -


i need xsl transformation of different xml responses, inserting processing instructions in identify list elements later xmltojson conversion.

example input xml:

<?xml version="1.0" encoding="utf-8"?> <recipe_collection>    <last_updated>20170405</last_updated>    <recipe>       <name>split pea soup</name>       <ingredients_list>          <ingredient>             <name>split peas</name>             <amount>1 bag</amount>          </ingredient>          <ingredient>             <name>vegetable broth</name>             <amount>32 ounces</amount>          </ingredient>          <ingredient>             <name>vegetable broth</name>             <amount>32 ounces</amount>          </ingredient>          <ingredient>             <name>ham</name>             <amount>small</amount>          </ingredient>       </ingredients_list>       <preparation>          <step>rinse peas</step>          <step>add ingredients pressure cooker</step>          <step>cook @ full pressure 12 minutes</step>          <step>season salt, pepper, garlic powder taste</step>       </preparation>       <serve_with>          <name>bread</name>       </serve_with>    </recipe> </recipe_collection> 

example xsl:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/xsl/transform" version="1.0">     <xsl:template match="node()|@*">       <xsl:copy>          <xsl:apply-templates select="node()|@*" />       </xsl:copy>    </xsl:template>     <xsl:template match="/recipe_collection/recipe/name[1]|/recipe_collection/recipe/ingredients_list/ingredient[1]|/recipe_collection/recipe/ingredients_list/ingredient[1]|/recipe_collection/recipe/preparation/step[1]|/recipe_collection/recipe/serve_with/name[1]">       <xsl:processing-instruction name="xml-multiple">          <xsl:value-of select="local-name()" />       </xsl:processing-instruction>       <xsl:copy>          <xsl:apply-templates select="node()|@*" />       </xsl:copy>    </xsl:template>  </xsl:stylesheet> 

which in turn copies original xml <?xml-muliple ...?> pis inserted:

<?xml version="1.0" encoding="utf-8"?> <recipe_collection>    <last_updated>20170405</last_updated>    <recipe>       <?xml-multiple name?>       <name>split pea soup</name>       <ingredients_list>          <?xml-multiple ingredient?>          <ingredient>             <name>split peas</name>             <amount>1 bag</amount>          </ingredient>          <ingredient>             <name>vegetable broth</name>             <amount>32 ounces</amount>          </ingredient>          <ingredient>             <name>vegetable broth</name>             <amount>32 ounces</amount>          </ingredient>          <ingredient>             <name>ham</name>             <amount>small</amount>          </ingredient>       </ingredients_list>       <preparation>          <?xml-multiple step?>          <step>rinse peas</step>          <step>add ingredients pressure cooker</step>          <step>cook @ full pressure 12 minutes</step>          <step>season salt, pepper, garlic powder taste</step>       </preparation>       <serve_with>          <?xml-multiple name?>          <name>bread</name>       </serve_with>    </recipe> </recipe_collection> 

so far good. make xsl work different xml schemas. pass in parameter containing paths used in match.

in modified stylesheet, i'm defining parameter "xpaths" list of default paths (note, value param passed xsl during runtime):

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/xsl/transform" version="1.0">     <xsl:param name="xpaths">/recipe_collection/recipe/name[1]|/recipe_collection/recipe/ingredients_list/ingredient[1]|/recipe_collection/recipe/ingredients_list/ingredient[1]|/recipe_collection/recipe/preparation/step[1]|/recipe_collection/recipe/serve_with/name[1]</xsl:param>     <xsl:template match="node()|@*">       <xsl:copy>          <xsl:apply-templates select="node()|@*" />       </xsl:copy>    </xsl:template>     <xsl:template match="$xpaths">       <xsl:processing-instruction name="xml-multiple">          <xsl:value-of select="local-name()" />       </xsl:processing-instruction>       <xsl:copy>          <xsl:apply-templates select="node()|@*" />       </xsl:copy>    </xsl:template>  </xsl:stylesheet> 

however match="$xpaths" in new xsl invalid

other things note:

the xsl parser i'm using allows xsl 2.0.

the xsl must work schema including ones elements may not have unique names, full xpath must used specify lists.

and apologies being xsl newb. still have trouble getting brain around of transformation concepts.

thanks pointers in right direction (or solutions).

with xslt 3.0 processor saxon 9.7 ee or pe should able use static variable , shadow attribute e.g.

  <xsl:param name="xpaths" static="yes" as="xs:string">/recipe_collection/recipe/name[1]|/recipe_collection/recipe/ingredients_list/ingredient[1]|/recipe_collection/recipe/ingredients_list/ingredient[1]|/recipe_collection/recipe/preparation/step[1]|/recipe_collection/recipe/serve_with/name[1]</xsl:param>     <xsl:template _match="{$xpaths}">       <xsl:processing-instruction name="xml-multiple">          <xsl:value-of select="local-name()" />       </xsl:processing-instruction>       <xsl:copy>          <xsl:apply-templates select="node()|@*" />       </xsl:copy>    </xsl:template> 

with pure xslt 2.0 need use 1 stylesheet taking string path(s) argument output/generate desired second stylesheet inserted match attribute value.


Comments