3

OK, the docs for Python's libxml2 bindings are really ****. My problem:

An XML document is stored in a string variable in Python. The string is a instance of Unicode, and there are non-ASCII characters in it. I want to parse it with libxml2, looking something like this:

# -*- coding: utf-8 -*-
import libxml2

DOC = u"""<?xml version="1.0" encoding="UTF-8"?>
<data>
  <something>Bäääh!</something>
</data>
"""

xml_doc = libxml2.parseDoc(DOC)

with this result:

Traceback (most recent call last):
  File "test.py", line 13, in <module>
    xml_doc = libxml2.parseDoc(DOC)
  File "c:\Python26\lib\site-packages\libxml2.py", line 1237, in parseDoc
    ret = libxml2mod.xmlParseDoc(cur)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 46-48:
ordinal not in range(128)

The point is the u"..." declaration. If I replace it with a simple "..", then everything is ok. Unfortunately it doesn't work in my setup, because DOC will definitely be a Unicode instance.

Has anyone an idea how libxml2 can be brought to parse UTF-8 encoded strings?

2
  • u"..." is a unicode string, its internal encoding is not something you care about, it's not UTF-8. Commented Oct 14, 2009 at 21:48
  • Also applies to urrllib2, etc. Commented Oct 14, 2009 at 22:25

2 Answers 2

9

It should be

# -*- coding: utf-8 -*-
import libxml2

DOC = u"""<?xml version="1.0" encoding="UTF-8"?>
<data>
  <something>Bäääh!</something>
</data>
""".encode("UTF-8")

xml_doc = libxml2.parseDoc(DOC)

The .encode("UTF-8") is needed to get the binary representation of the unicode string with the utf8 encoding.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the answer, it works perfectly. Andrey was first, though.
6

XML is a binary format, despite of looking like a text. An encoding is specified in the beginning of the XML file in order to decode the XML bytes into the text.

What you should do is to pass str, not unicode to your library:

xml_doc = libxml2.parseDoc(DOC.encode("UTF-8"))

(Although some tricks are possible with site.setencoding if you are interested in reading or writing unicode strings with automatic conversion via locale.)

Edit: The Unicode article by Joel Spolsky is good guide to string characters vs. bytes, encodings, etc.

1 Comment

Thanks for the answer! OK, I guess I have to think again about strings in Python (although it would be nice of libxml2, if it would accept basestring instances).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.