XSL How to copy identical + add copy with attributes changes
I need to copy a node an开发者_开发知识库d its sub-nodes:
- first: one identical copy
- followed by a modified copy with some attributes values changed
Here is the extract to change:
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
WarningLevel="4"
SuppressStartupBanner="TRUE"
DebugInformationFormat="4"
CompileAs="0"/>
</Configuration>
In the second copy I need to change all "Debug" to "Release" and some attribute values also.
Thanks
Thanks Koynov
I found however a solution using template modes:
<xsl:template match="Configuration[@Name='Debug|Win32']">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
<xsl:copy>
<xsl:attribute name="WholeProgramOptimization">TRUE</xsl:attribute>
<xsl:apply-templates select="@*|node()" mode="Release"/>
</xsl:copy>
</xsl:template>
With this template for all attributes:
<xsl:template match="@*" mode="Release">
<xsl:attribute name="{local-name()}">
<xsl:call-template name="replace-string">
<xsl:with-param name="text" select="."/>
<xsl:with-param name="replace" select="'Debug'"/>
<xsl:with-param name="with" select="'Release'"/>
</xsl:call-template>
</xsl:attribute>
</xsl:template>
and of-course the "replace-string" template.
Thanks again.
Here is a xslt transformation for your needs:
<xsl:template match="Configuration">
<xsl:copy-of select="."/>
<xsl:call-template name="CopyWithReplace">
<xsl:with-param name="Node" select="."/>
<xsl:with-param name="PatternToReplace" select="string('Debug')"/>
<xsl:with-param name="ValueToReplaceWith" select="string('Release')"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="CopyWithReplace">
<xsl:param name="Node"/>
<xsl:param name="PatternToReplace"/>
<xsl:param name="ValueToReplaceWith"/>
<xsl:variable name="ReplacedNodeName">
<xsl:call-template name="SearchAndReplace">
<xsl:with-param name="input" select="name($Node)"/>
<xsl:with-param name="search-string" select="$PatternToReplace"/>
<xsl:with-param name="replace-string" select="$ValueToReplaceWith"/> </xsl:call-template>
</xsl:variable>
<xsl:element name="{$ReplacedNodeName}">
<xsl:for-each select="@*">
<xsl:variable name="ReplacedAttributeName">
<xsl:call-template name="SearchAndReplace">
<xsl:with-param name="input" select="name()"/>
<xsl:with-param name="search-string" select="$PatternToReplace"/>
<xsl:with-param name="replace-string" select="$ValueToReplaceWith"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="ReplacedAttributeValue">
<xsl:call-template name="SearchAndReplace">
<xsl:with-param name="input" select="."/>
<xsl:with-param name="search-string" select="$PatternToReplace"/>
<xsl:with-param name="replace-string" select="$ValueToReplaceWith"/>
</xsl:call-template>
</xsl:variable>
<xsl:attribute name="{$ReplacedAttributeName}">
<xsl:value-of select="$ReplacedAttributeValue"/>
</xsl:attribute>
</xsl:for-each>
<xsl:for-each select="child::*" >
<xsl:call-template name="CopyWithReplace">
<xsl:with-param name="Node" select="."/>
<xsl:with-param name="PatternToReplace" select="$PatternToReplace"/>
<xsl:with-param name="ValueToReplaceWith" select="$ValueToReplaceWith"/>
</xsl:call-template>
</xsl:for-each>
</xsl:element>
</xsl:template>
<xsl:template name="SearchAndReplace">
<xsl:param name="input"/>
<xsl:param name="search-string"/>
<xsl:param name="replace-string"/>
<xsl:choose>
<!-- See if the input contains the search string -->
<xsl:when test="$search-string and contains($input,$search-string)">
<!-- If so, then concatenate the substring before the search string to the replacement string
and to the result of recursively applying this template to the remaining substring. -->
<xsl:value-of select="substring-before($input,$search-string)"/>
<xsl:value-of select="$replace-string"/>
<xsl:call-template name="SearchAndReplace">
<xsl:with-param name="input" select="substring-after($input,$search-string)"/>
<xsl:with-param name="search-string" select="$search-string"/>
<xsl:with-param name="replace-string" select="$replace-string"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<!-- There are no more occurrences of the search string so just return the current input string -->
<xsl:value-of select="$input"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Good luck.
精彩评论