Home > other >  How to replace part of a string with XSLT?
How to replace part of a string with XSLT?

Time:09-02

I have the following XML where I need to replace part of an attributes value (an update to a Java package name) but can't seem to get it working. The below just does a direct replacement and I lose the class name from the string e.g. it just transforms clazz to "com.example.main".

I have also tried using contains (@*[contains(.,"substring")]) instead of .= to try and replace the package name but no luck. Any help appreciated, thanks.

XML:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<MyConfiguration>
    <modules>
        <root>
            <mappings>
                <pojoMapping name="MyClass">
                    <id>104</id>
                    <clazz value="com.example.MyClass"/>
                </pojoMapping>
            </mappings>
        </root>
    </modules>
</MyConfiguration>

XSLT:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template name="update-package-name" match="mappings/pojoMapping/clazz/@value[.='com.example']">
        <xsl:attribute name="value">com.example.main</xsl:attribute>
    </xsl:template>

</xsl:stylesheet>

CodePudding user response:

How about:

XSLT 2.0

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="clazz/@value[contains(., 'com.example')]">
    <xsl:attribute name="value" select="replace(., 'com\.example', 'com.example.main')"/>
</xsl:template>

</xsl:stylesheet>

Note that this replaces com.example with com.example.main anywhere in the string. If you want to limit the replacement to only when the string starts with the search string, then do:

<xsl:template match="clazz/@value[starts-with(., 'com.example')]">
    <xsl:attribute name="value" select="replace(., '^com\.example', 'com.example.main')"/>
</xsl:template>

CodePudding user response:

This one could do it:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*,node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="mappings/pojoMapping/clazz/@value[starts-with(., 'com.example')]">
        <xsl:attribute name="value" select="replace(., 'com[.]example', 'com.example.main')" />
    </xsl:template>

</xsl:stylesheet>
  • Related