Strips DOCTYPE from XML document, returns (rss_version, stripped_data) rss_version may be 'rss091n' or None stripped_data is the same XML document, minus the DOCTYPE
(data)
| 3747 | return newdata.encode('utf-8') |
| 3748 | |
| 3749 | def _stripDoctype(data): |
| 3750 | '''Strips DOCTYPE from XML document, returns (rss_version, stripped_data) |
| 3751 | |
| 3752 | rss_version may be 'rss091n' or None |
| 3753 | stripped_data is the same XML document, minus the DOCTYPE |
| 3754 | ''' |
| 3755 | start = re.search(_s2bytes('<\w'), data) |
| 3756 | start = start and start.start() or -1 |
| 3757 | head,data = data[:start+1], data[start+1:] |
| 3758 | |
| 3759 | entity_pattern = re.compile(_s2bytes(r'^\s*<!ENTITY([^>]*?)>'), re.MULTILINE) |
| 3760 | entity_results=entity_pattern.findall(head) |
| 3761 | head = entity_pattern.sub(_s2bytes(''), head) |
| 3762 | doctype_pattern = re.compile(_s2bytes(r'^\s*<!DOCTYPE([^>]*?)>'), re.MULTILINE) |
| 3763 | doctype_results = doctype_pattern.findall(head) |
| 3764 | doctype = doctype_results and doctype_results[0] or _s2bytes('') |
| 3765 | if doctype.lower().count(_s2bytes('netscape')): |
| 3766 | version = u'rss091n' |
| 3767 | else: |
| 3768 | version = None |
| 3769 | |
| 3770 | # only allow in 'safe' inline entity definitions |
| 3771 | replacement=_s2bytes('') |
| 3772 | if len(doctype_results)==1 and entity_results: |
| 3773 | safe_pattern=re.compile(_s2bytes('\s+(\w+)\s+"(&#\w+;|[^&"]*)"')) |
| 3774 | safe_entities=filter(lambda e: safe_pattern.match(e),entity_results) |
| 3775 | if safe_entities: |
| 3776 | replacement=_s2bytes('<!DOCTYPE feed [\n <!ENTITY') + _s2bytes('>\n <!ENTITY ').join(safe_entities) + _s2bytes('>\n]>') |
| 3777 | data = doctype_pattern.sub(replacement, head) + data |
| 3778 | |
| 3779 | return version, data, dict(replacement and [(k.decode('utf-8'), v.decode('utf-8')) for k, v in safe_pattern.findall(replacement)]) |
| 3780 | |
| 3781 | def parse(url_file_stream_or_string, etag=None, modified=None, agent=None, referrer=None, handlers=None, request_headers=None, response_headers=None): |
| 3782 | '''Parse a feed from a URL, file, stream, or string. |
no test coverage detected
searching dependent graphs…