3

This is obviously a SSCCE.

I have the following template file:

xml(value)::=<<
<a>
    <b>
        ^value^
    </b>
</a>
>>

... with the following code:

private static final String VALUE="alpha\nbeta";
public static void main(String args[]) throws Exception {
    STGroup stGroup = new STGroupFile("templates/a.xml.stg", '^', '^');
    ST st = stGroup.getInstanceOf("xml");
    st.add("value", VALUE);
    System.out.printf("--------\n%s\n--------", st.render());
}

The code produces:

 [java] --------
 [java] <a>
 [java]     <b>
 [java]         alpha
 [java]         beta
 [java]     </b>
 [java] </a>
 [java] --------

In other words, the String value is modified as whitespace is added. When a client parses the XML file, even with whitespace trimming, the String value will be perceived as changed as whitespace has been added inside the String.

I understand that a solution is to declare the template as:

xml(value)::=<<
<a>
    <b>^value^</b>
</a>
>>

... but even this solution necessitates that all other nodes which may contain the xml rendering are also right-justified.

E.g., assuming that the above rendered value is embedded in another template, then the following template:

enclosing-document(xml)::=<<
<h1>
    <h2>
        ^xml^
    </h2>
</h1>
>>

... will also have to be re-written as:

enclosing-document(xml)::=<<
<h1>
    <h2>
^xml^
    </h2>
</h1>
>>

... in effect necessitating the left-justification of all nodes to be sure.

Is there a way to instruct StringTemplate to just emit a particular String parameter as it is (without indenting it in case of new lines present within) while at the same time preserve whitespace / indentation for all other cases (so that my rendered output will not be ugly)?

Update

I tried using the NoIndentWriter but was met with other problems. So it appears that the NoIndentWriter does indeed emit the multiline String as it is but does not honor whitespace present in the template file. So I am back at square one.

Community
  • 1
  • 1
Marcus Junius Brutus
  • 26,087
  • 41
  • 189
  • 331
  • Would enclosing the content in `<![CDATA[]]>` section change the result? – Sergey Kalinichenko Jan 11 '15 at 17:39
  • @dasblinkenlight I am not sure I understand what you propose. At any rate, if CDATA is added in the template, then nothing changes in respect to the insertion of whitespace during the indentation of the multi-line String. Further, I am not sure adding a CDATA section in my final document is free from side-effects. – Marcus Junius Brutus Jan 11 '15 at 17:52
  • I was thinking about `<![CDATA[^value^]]>`, hoping that stringtemplate would pay attention to `CDATA` sections. It looks like it doesn't. Oh well... – Sergey Kalinichenko Jan 11 '15 at 17:56
  • 1
    Maybe try a different templating engine? FreeMarker? Velocity? Or since you're generating XML, why not use an XML generation library? Xerces, XStream, Smooks, etc. – Mike Clark Jan 13 '15 at 20:44
  • @MikeClark I 'd like to upvote the code you previously added and accept it as a solution as it's the best that can be done given the limitations (even though it does lose all indentation). – Marcus Junius Brutus Jan 13 '15 at 20:52
  • @MarcusJuniusBrutus [Your approach to using NoIndentWriter](http://stackoverflow.com/q/27931007/274677) is much more elegant than my code, since your approach does not require complicated subclassing. I think we achieve the same effect but you use far less code. I suggest you answer your own question with that code and accept it. :) – Mike Clark Jan 13 '15 at 21:01

1 Answers1

0

So in the end what I did was to use the NoIndentWriter with the code given in this post. Then, to solve the lack of indentation that results in ugly XML (complained about in the aforementioned post), I used the XML pretty-printer described here.

Community
  • 1
  • 1
Marcus Junius Brutus
  • 26,087
  • 41
  • 189
  • 331