Reputation: 23
I'm using XmlTemplateEngine to create several XML files. Currently I have a case where the XML generation fails. It fails if a single quote is used as a value of a xml tag.
Here is the method:
public static void mergeXmlTemplateToFile(File src, File dest, Map bindings){
File part = new File(FileUtils.getTempDirectoryPath()+"/"+src.name)
new XmlTemplateEngine().createTemplate(src).make(bindings).writeTo(new PrintWriter(part))
XMLMerger merger = new XMLMerger(part, dest)
merger.merge();
part.delete()
}
call:
BuildUtils.mergeXmlTemplateToFile(new File(template+"area/cms/sharepoint.xml"), new File(output+"area/conf/config_complete.xml"), [servers:Builder.config.area.cms.sharepoint.servers, hostnames:Builder.config.server.hostnames])
The problem is, that the temporary file and the value of date.format has single quotes. The value of date.format need the single quotes. XmlTemplateEngine cannot use double quotes. I cannot use the temporary file for the next steps, because it's not valid. [Fatal Error] sharepoint.xml: Element type "property" must be followed by either attribute specifications, ">" or "/>". Because this is not valid:
<property name='date.format' value='yyyy-MMdd'T'HH:mm:ss'Z''/>
Temporary file:
<config>
<cms>
<type name='SharePoint'>
<host ident=''>
<property name='user' value='demo'/>
<property name='password' value='pass'/>
<property name='domain' value='example.com'/>
<property name='date.format' value='yyyy-MMdd'T'HH:mm:ss'Z''/>
</host>
</type>
</cms>
</config>
The template:
<config xmlns:gsp="http://groovy.codehaus.org/2005/gsp">
<cms>
<ctype name="SharePoint">
<gsp:scriptlet>servers.server.each { server -></gsp:scriptlet>
<host ident="${server.ident.text()}">
<property name="user" value="${server.user.text()}" />
<property name="password" value="${server.password.text()}" />
<property name="domain" value="${server.domain.text()}" />
<property name="date.format" value="${server.dateformat.text()}" />
</host>
<gsp:scriptlet>}</gsp:scriptlet>
</type>
</cms>
I have tried to use MarkupTemplateEngine instead of XmlTemplateEngine, but I had no success. http://www.groovy-lang.org/templating.html#_the_markuptemplateengine
TemplateConfiguration config = new TemplateConfiguration();
config.useDoubleQuotes = true;
MarkupTemplateEngine engine = new MarkupTemplateEngine(config);
engine.createTemplate(src).make(bindings).writeTo(new PrintWriter(part))
import groovy.util.logging.Log4j;
import javax.xml.parsers.DocumentBuilder
import javax.xml.parsers.DocumentBuilderFactory
import org.atteo.xmlcombiner.XmlCombiner
import com.google.common.collect.Lists;
@Log4j
class XMLMerger {
File src
File dest
public XMLMerger(File src, File dest){
this.src = src
this.dest = dest
}
public void merge(){
merge(null)
}
public void merge(String id){
if(src.exists() && dest.exists()){
DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
XmlCombiner combiner = new XmlCombiner();
if(id != null)
combiner = new XmlCombiner(id);
combiner.combine(docBuilder.parse(dest))
combiner.combine(docBuilder.parse(src))
combiner.buildDocument(dest.toPath())
}
}
}
The problem occurs before the XMLMerger is called. Here is a example regarding the XmlTemplateEngine you can run online: http://goo.gl/A0pxfs
Thanks
Upvotes: 2
Views: 401
Reputation: 171144
There's a utility method in XmlUtil
called escapeXml
, so you can do:
import groovy.text.XmlTemplateEngine
import static groovy.xml.XmlUtil.escapeXml
// Escape values going in to the binding
def binding = [dateformat: escapeXml("yyyy-MMdd'T'HH:mm:ss'Z'")]
def engine = new XmlTemplateEngine()
def text = '''<config xmlns:gsp="http://groovy.codehaus.org/2005/gsp">
| <cms>
| <type name="SharePoint">
| <host ident="">
| <property name="user" value="" />
| <property name="password" value="" />
| <property name="domain" value="" />
| <property name="date.format" value="${dateformat}" />
| </host>
| </type>
| </cms>
|</config>'''.stripMargin()
def template = engine.createTemplate(text).make(binding)
println template.toString()
Upvotes: 2