0

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>
2
  • 1
    Please explain exactly which part you want to keep and which part you want to replace with what. IOW, what are the rules you want to implement. Commented Sep 1, 2022 at 10:55
  • I need to replace 'com.example' from 'com.example.MyClass' with 'com.example.main'. The transformation would be 'com.example.MyClass' -> 'com.example.main.MyClass'. Commented Sep 1, 2022 at 11:06

2 Answers 2

2

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>
Sign up to request clarification or add additional context in comments.

2 Comments

Awesome, that worked, thanks very much. May I ask what is the '\' for after the 'com' in the replace function?
The 2nd argument of the replace() function is a regex pattern. A dot in a regex pattern matches any single character. In order to match only an actual dot, it needs to be escaped.
0

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>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.