I have an XML
<?xml version="1.0" encoding="utf-8"?>
<CATALOG>
<PLANT COLOR="@DYNAMIC_COLOR@">
<COMMON>Bloodroot</COMMON>
<BOTANICAL>Sanguinaria canadensis</BOTANICAL>
<ZONE>4</ZONE>
<LIGHT>Mostly Shady</LIGHT>
<PRICE>@DYNAMIC_PRICE@</PRICE>
<AVAILABILITY>031599</AVAILABILITY>
</PLANT>
<PLANT COLOR="RED" TYPE="@DYNAMIC_TYPE@">
<COMMON>Columbine</COMMON>
<BOTANICAL>Aquilegia canadensis</BOTANICAL>
<ZONE>3</ZONE>
<LIGHT>Mostly Shady</LIGHT>
<PRICE>$9.37</PRICE>
<AVAILABILITY>030699</AVAILABILITY>
</PLANT>
</CATALOG>
I want to transform to
<?xml version="1.0" encoding="utf-8"?>
<CATALOG>
<PLANT COLOR="RED">
<COMMON>Bloodroot</COMMON>
<BOTANICAL>Sanguinaria canadensis</BOTANICAL>
<ZONE>4</ZONE>
<LIGHT>Mostly Shady</LIGHT>
<PRICE>10</PRICE>
<AVAILABILITY>031599</AVAILABILITY>
</PLANT>
<PLANT COLOR="RED" TYPE="HERBS">
<COMMON>Columbine</COMMON>
<BOTANICAL>Aquilegia canadensis</BOTANICAL>
<ZONE>3</ZONE>
<LIGHT>Mostly Shady</LIGHT>
<PRICE>$9.37</PRICE>
<AVAILABILITY>030699</AVAILABILITY>
</PLANT>
</CATALOG>
Basically, i want to replace "@DYNAMIC_*@" attribute/element value with a predefined values. Please help!!! I can do with for each and exactly finding the values and replace it with the desired values. But i prefer to use apply template concept.
A neat solution for this kind of problem is to transform your skeleton XML document into a stylesheet. Write a transformation that converts it to:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0" expand-text="yes">
<xsl:param name="DYNAMIC_COLOR"/>
<xsl:param name="DYNAMIC_TYPE"/>
<xsl:template name="xsl:initial-template">
<CATALOG>
<PLANT COLOR="{$DYNAMIC_COLOR}">
<COMMON>Bloodroot</COMMON>
<BOTANICAL>Sanguinaria canadensis</BOTANICAL>
<ZONE>4</ZONE>
<LIGHT>Mostly Shady</LIGHT>
<PRICE>{$DYNAMIC_PRICE}</PRICE>
<AVAILABILITY>031599</AVAILABILITY>
</PLANT>
<PLANT COLOR="RED" TYPE="{$DYNAMIC_TYPE}">
<COMMON>Columbine</COMMON>
<BOTANICAL>Aquilegia canadensis</BOTANICAL>
<ZONE>3</ZONE>
<LIGHT>Mostly Shady</LIGHT>
<PRICE>$9.37</PRICE>
<AVAILABILITY>030699</AVAILABILITY>
</PLANT>
</CATALOG>
</xsl:template>
</xsl:stylesheet>
and then execute this stylesheet with entry point "xsl:initial-template" and with values for the parameters. I've used XSLT 3.0 value templates here to make it a bit easier; if you want to use XSLT 2.0 you can generate xsl:value-of instructions instead.
The basic logic for the conversion is
<xsl:stylesheet ...>
<xsl:namespace-alias stylesheet-prefix="z" result-prefix="xsl"/>
<xsl:variable name="params" select="distinct-values(
(//@*|//text())[matches(., '^@.*@^')]!translate(., '@', ''))"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="/">
<z:stylesheet version="3.0" expand-text="yes">
<xsl:for-each select="$params">
<z:param name="{.}"/>
</xsl:for-each>
<z:template name="xsl:initial-template">
<xsl:apply-templates/>
</z:template>
</z:stylesheet>
</xsl:template>
<xsl:template match="@*[matches(., '^@.*@$')]">
<xsl:attribute name="{name()}" select="replace(., '^@(.*)@$', '{\$$1}')"/>
</xsl:template>
<xsl:template match="text()[matches(., '^@.*@$')]">
<!-- 3.0 -->
<!-- <xsl:value-of select="replace(., '^@(.*)@$', '{\$$1}')"/> -->
<!-- 2.0 -->
<z:value-of select="replace(., '^@(.*)@$', '\$$1'"/>
</xsl:template>
</xsl:stylesheet>
You may need to do a bit more work if there are attributes or text nodes that contain curly braces: these need to be doubled.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.