STIXProject/python-stix — pull request #217 by bworrell (2014-10-14 20:52:34+00:00)
Title: Issue 10: CDATA

This starts to address #10.
* Added `stix.utils.cdata()` method which wraps input in `` block.
* Added `stix.utils.strip_cdata()` method which removes all CDATA blocks from input (and xml unescapes everything).
* Moved many duplicated binding methods and classes to `stix.bindings.__init__`
* Binding modules now all have `from stix.bindings import *` in them
* Changed binding `quote_xml()` and `quote_attrib()` methods to use `xml.sax.saxutils` methods
* Changed `quote_xml()` method to return input untouched if the input is a CDATA block (so the CDATA block isn't escaped).

#10 was getting at the fact that CDATA blocks were lost if you parsed a document containing CDATA and then called `to_xml()` (your CDATA blocks would disappear, and escaped XML would remain). I had hoped that it would be easy to maintain the CDATA blocks round-trip, but it seems like `lxml` (or maybe `libxml2`) makes that difficult by stripping CDATA. Calling `node.text` on an `etree._Element` node will never contain CDATA [source](http://lxml.de/api.html#cdata).

Example:
```
>>> s = StringIO("test")
>>> parser = etree.ETCompatXMLParser(strip_cdata=False)
>>> e = etree.parse(s, parser=parser)
>>> r = e.getroot()
>>> r.text
'test'
>>> print etree.tostring(r)
test
```

The `.text` property doesn't show CDATA, even though it's there on `etree.tostring()`. The bindings make heavy use of `.text`, so the presence of CDATA isn't captured easily. It could be possible to replace all `.text` access code with calls to the binding `get_all_text()` method, which could inspect the output of `etree.tostring()` for CDATA, and then wrap the input with a CDATA block. The API code would then need to be adjusted to know how to work with it.

I don't think this doesn't close out #10, but the two utility methods help the situation.