multiple text replacements in string by markers
<p>I have an xml file that is used as a template.
I have multiple markers inside this xml that will be replaced with actual data. This is what i did:<br/></p>

<pre><code>def populate_template(self, value1, value2, value3):
        with open('my_template.xml', 'rb') as xml_template:
            template_string = xml_template.read()

        template_string.replace('{{MARKER_1}}', value1)
        template_string.replace('{{MARKER_2}}', value2)
        template_string.replace('{{MARKER_3}}', value3)  
        return template_string
</code></pre>

<p>Each marker can appear multiple times inside the template.<br/>
I was wondering if there is a more efficient way of doing this?<br/>
<strong>Tech stuff:</strong></p>

<ul>
<li>Python 2.7</li>
</ul>

<p>Yes. Use the <code>jinja2</code> templating module. To use your existing template you could do something like this:</p>

<pre><code>def populate_template(self, value1, value2, value3):
    from jinja2 import Template
    t = Template(open('my_template.xml', 'r').read())
    output = t.render(MARKER_1=value2, MARKER_2=value2, MARKER_3=value3)
    return output
</code></pre>

<p>It's well worth studying the different ways you can pass arguments to the template, also. For example the same code could have been written as...</p>

<pre><code>    ...
    context = {'MARKER_1': value1, 'MARKER_2', value2, 'MARKER_3': value3}
    output = t.render(**context)
</code></pre>

<p>and you can use this trick with any old dicts you happen to have lying around. It's a great way of extracting readable information from dicts selectively.</p>

<p>The designers of jinja2, being smart cookies sympathetic to the Python cause, have in fact helped you by allowing you to provide the context in any of the ways you can create a dict (keyword arguments, a list of <code>(key, value)</code> tuples or a dict - including other dict-like things such as <code>collections.OrderedDict</code>). So you could also write the second line as</p>

<pre><code>    output = t.render(context)
</code></pre>

<p>which is both more readable and more efficient (I'm guessing, but it's an informed guess).</p>

python xml string python-2.7 replace