Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replacing value in an XML file using Ant

Tags:

ant

I'm trying to automize my android build process. For that, I want to change the app name in an XML file. the code is something like this

<resources>
   <string name="app_name">Realta Connections</string>
</resources>

Now I want to replace the name 'Realta Connections' by something else at build time, a name which I would give at build time. The name can be 'Realta Connections' or anything else, so I need to detect the name="app_name" and replace the content inside it. I tried looking for how to do it but couldn't find the precise way. How can I do that? Please help.

like image 764
ghostCoder Avatar asked Dec 30 '25 20:12

ghostCoder


2 Answers

It is probaly easiest to have a fixed value, which will be replaced. This will allow the use of the replace task: You need replacetoken/replacevalue and the Strings inside ![CDATA[]] because of the xml characters.

  <replace casesensitive="false" 
    file="../KS.build/ivy.properties">
    <replacetoken><![CDATA[<string name="app_name">Realta Connections</string>]]></replacetoken>  
    <replacevalue><![CDATA[<string name="app_name">Something else</string>]]></replacevalue>  
  </replace>

Otherwise there is no normal ant solution (repleaceregex doesn't allow nested CDATA replacements).

Links:

  • Ant replace task
like image 88
oers Avatar answered Jan 01 '26 16:01

oers


I know this question is quite old, but here is an idea. This seems like it's not really a purely ant solution, but you can embed a script in ant using the <scriptdef> tag.

Here is a function you can use to search for something in an XML file and store the result in a property:

<scriptdef name="xpath-query" language="javascript">
        <attribute name="query"/>
    <attribute name="xmlfile"/>
    <attribute name="property"/>
     <![CDATA[
        importClass(java.io.FileInputStream);
        importClass(javax.xml.xpath.XPath);
        importClass(javax.xml.xpath.XPathConstants);
        importClass(javax.xml.xpath.XPathFactory);
        importClass(org.xml.sax.InputSource);
        importClass(java.lang.System);


        var exp = attributes.get("query");          
        var filename = attributes.get("xmlfile");
        var xpath = XPathFactory.newInstance().newXPath();          
        var input = new InputSource(new FileInputStream(filename));
        var value = xpath.evaluate(exp, input, XPathConstants.STRING);          
        self.project.setProperty( attributes.get("property"), value );          
        System.out.println("Copied this value:" + value + " to this property:" + attributes.get("property"));

    ]]>
</scriptdef>

Then you could get the current name of the app by using the xpath-query task you just defined:

<xpath-query query='pathToResources\resources\string[@name="app_name"]' xmlFile="app.xml" property="appName" />

Then the app name will be stored in the property appName.

From there you could do regex replace on the xml file using the app name.

<replaceregexp file="app.xml" match="${appName}" replace="${newAppName}" />

The potential down-side of this particular approach is that if you have the same app name string somewhere else in the XML file the regex replace may replace something you didn't intend.

You could probably define the <scriptdef> to do the replacement rather than just storing what was found in a property, but I had this portion of code handy already.

like image 37
ksun Avatar answered Jan 01 '26 17:01

ksun