Example of rendering CDATA
jezen opened this issue · 6 comments
Is there a way to wrap some values in CDATA for only a subset of an XML document? I can only find how to change the settings so that every field has its contents wrapped in CDATA.
Alternatively, is there way to render an XML document inside another XML document?
Or another alternative: Is there something roughly equivalent to preEscapedToMarkup
?
I'm not quite sure what your goal is here, or what layer of the API you're working at here. Perhaps a higher level question would make sense here.
@snoyberg Here's a minimal way to reproduce the problem.
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
import Data.Map (empty)
import Data.Text (Text, unpack)
import Data.Text.Lazy (toStrict)
import Text.Hamlet.XML (xml)
import Text.XML
settings :: RenderSettings
settings = def
{ rsXMLDeclaration = False
, rsPretty = True
}
doc :: Document
doc = Document prologue document []
where
prologue = Prologue [] Nothing []
document = Element "ieXMLDocument" empty nodes
nodes :: [Node]
nodes = [xml|
<survey>
^{concat nodes'}
|]
where nodes' = [ foo, bar, baz ]
foo' :: Text
foo' = "foo"
bar' :: Text
bar' = "bar"
baz' :: Text
baz' = "baz"
foo :: [Node]
foo = [xml|
<Foo>#{foo'}
|]
bar :: [Node]
bar = [xml|
<Bar>
<![CDATA[ #{bar'} ]]>
|]
baz :: [Node]
baz = [xml|
<Baz>#{baz'}
|]
main :: IO ()
main = putStrLn $ unpack $ toStrict $ renderText settings doc
And here is the output:
<ieXMLDocument>
<survey>
<Foo>
foo
</Foo>
<Bar>
<![CDATA[ #{bar'}="" ]]=""/>
</Bar>
<Baz>
baz
</Baz>
</survey>
</ieXMLDocument>
Rather than the above output, I would like output such as the following:
<ieXMLDocument>
<survey>
<Foo>
foo
</Foo>
<Bar>
<![CDATA[ bar ]]>
</Bar>
<Baz>
baz
</Baz>
</survey>
</ieXMLDocument>
As you can see, I only want to wrap the content of one node in CDATA
. When I try using rsUseCDATA = const True
, I see in the rendered output that the content of every node is wrapped in CDATA
.
Why do you need a CDATA?
I’d like to dump a load of JSON inside an XML tag, and ideally for it to still be human-readable. As I understand it, without the CDATA some characters would need escaping. I expect these libraries handle escaping correctly, but that would mean the resulting JSON is slightly less human-readable.
Also, I may be using rsUseCDATA
incorrectly — I’m giving it const True
, which was taken from the only example I could find (which was in the test suite).
Ok, fair enough. This issue can be closed in that case.