Configuration/XML Transformation Examples (Ant)

<project name="dpbuddy.samples.transform" xmlns:dp="antlib:com.myarch.dpbuddy" >

    <description>
        Samples demonstrating transformation of DataPower config files and 
        other XML files
    </description>

    <target name="transform.import">

        <property name="wsproxy.xml.file" value="${dpconfig.home}/WSProxy.xml" />
        <property name="wsproxy.zip.file" value="${dpconfig.home}/WSProxy.zip" />

        <property name="dev.ws.port" value="8094" />
        <!-- 'workDir' points to the location where to unzip files-->
        <property name="work.dir" location="build/dpbuddy"/>

       <!-- Example of transforming configuration using setText and dpExclude -->
        <dp:buddyImport workDir="${work.dir}" file="${wsproxy.zip.file}" transformOnly="true">
            <!-- DPBuddy unzips the file and transforms the files specified in "includes".
            It will throw an error if the file is not a well-formed XML.
            'transformFiles' supports all attributes and elements of Ant fileset.
            You omit "transformFiles" and specify "transform" directly within the task
            if the only file being transformed is 'export.xml'
            -->
            <transformFiles includes="export.xml">
                <transform>
                    <!-- Set HTTPHanlder port to the value of the property -->
                    <setText xpath="//*[@name='TestHTTPHandler']/LocalPort" 
                        value="${ws.port}" />
                    <!-- prepend environment name to the value of the hostname.
                    You can reference any Ant property using Groovy variable in the script, e.g., 'env'.
                    'currentValue' is the variable containing the value of the matched text node or attribute.
                    -->
                    <setText xpath="//RemoteEndpointHostname" expression="env+'.'+currentValue" />
                    <!-- 'dpExclude'/'dpInclude' don't use xpath. Instead, you can simply provide regexps
                    matching names of DataPower classes and objects. -->
                    <!-- Exclude all HTTPUserAgents that begin with 'def', like 'default' -->
                    <dpExclude class="HTTPUserAgent" name="def.*"/>
                </transform>
            </transformFiles>
        </dp:buddyImport>

        <property name="lbg.xpath" value="//LoadBalancerGroup"/>
        <!-- Example of transformation using 'delete' and 'add' -->
        <dp:buddyImport file="${dpconfig.home}/LoadBalancerGroup.xml" transformOnly="true">
            <transform>
                <!-- Remove all existing group members so we can start from clean slate-->
                <delete xpath="//LBGroupMembers" />
                <!-- 'if' has to be true in order for the transformation to execute.
                You can use any boolean Groovy expression in 'if'. -->
                <!-- In our example, dev/test LBG has two members, prod has three -->
                <add xpath="${lbg.xpath}" if="env==~/(dev|test|prod).*/">
                    <LBGroupMembers>
                        <Server>prefix.server1</Server>
                        <Weight>1</Weight>
                        <MappedPort>9081</MappedPort>
                        <Activity/>
                        <HealthPort/>
                        <LBMemberState>enabled</LBMemberState>
                    </LBGroupMembers>
                    <LBGroupMembers>
                        <Server>prefix.server2</Server>
                        <Weight>1</Weight>
                        <MappedPort>9081</MappedPort>
                        <Activity/>
                        <HealthPort/>
                        <LBMemberState>enabled</LBMemberState>
                    </LBGroupMembers>
                </add>
                <!-- Production environment has an extra back-end server.
                Instead of using the value of property 'env', we can check the DataPower url.
                DataPower connection parameters are accessible using 'dp' map in Groovy.
                 -->
                <add xpath="${lbg.xpath}" if="dp.url.startsWith('https://prod.')">
                    <LBGroupMembers>
                        <Server>prefix.server3</Server>
                        <Weight>1</Weight>
                        <MappedPort>9081</MappedPort>
                        <Activity/>
                        <HealthPort/>
                        <LBMemberState>enabled</LBMemberState>
                    </LBGroupMembers>
                </add>

                <!-- Update server names according to the environment -->
                <setText xpath="//LBGroupMembers/Server" expression="currentValue.replace('prefix', env)" />

            </transform>
        </dp:buddyImport>
    </target>

    <!-- Transform directives are also available in the 'dp:copy' task.
    We can transform any well-formed XML file.
    -->

    <!-- Declare reusable group of transforms -->
    <dp:transform id="test.transform">
        <!-- To transform XML with namespaces, namespaces have to be declared -->
        <namespace prefix="buddy" uri="http://myarch.com/dpbuddy" />
        <setText xpath="//buddy:text-node" value="New value" /> 
        <!-- By default, if transform didn't match anything, it will raise an exception.
        We can suppress this by 'matchRequired'.
        -->
        <setText xpath="//buddy:non-existing-node" value="New value" matchRequired="false"/> 
    </dp:transform>


    <target name="transform.copy">
        <property name="text.replace.prop" value="new text"/>
        
        <dp:copy toDir="local:/wsdl" transformOnly="true">
            <dpFileset dir="${dpfiles.home}" includes="**/testFile.xml">
                <transform>
                    <!-- 'refid' will source the reusable group we declared earlier.
                    Transforms from 'test.transform' will be executed first.
                     -->
                    <transform refid="test.transform"/>
                    <!-- note how we can reference an Ant property containing dots in Groovy -->
                    <setText xpath="//buddy:text-node" expression="currentValue+'${text.replace.prop}'" 
                        if="this.'text.replace.prop'.contains('New')"/>
                    <!-- replaceText provides an easy way to do global replace in all attributes and text nodes -->
                    <!-- this will replace each occurrence of the substring "to replace" -->
                    <replaceText textToReplace="to replace" replaceWith="new value"/>
                </transform>
            </dpFileset>
        </dp:copy>
    </target>
                                                                        
    <target name="transform.all" depends="transform.import,transform.copy" />
</project>