Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Python (http://www.velocityreviews.com/forums/f43-python.html)
-   -   TypeError coercing to Unicode with field read from XML file (http://www.velocityreviews.com/forums/t355731-typeerror-coercing-to-unicode-with-field-read-from-xml-file.html)

Randall Parker 03-22-2006 01:41 AM

TypeError coercing to Unicode with field read from XML file
 
Running Python 2.4.2 on Windows in SPE. I have a very small XML file
(see below) that is in UTF-8 and saved by Windows Notepad as such. I'm
reading it with minidom.

My problem is that once I parse the file with minidom and a field from
it to another variable as shown with this line:
IPAddr = self.SocketSettingsObj.IPAddress

I get this error:

File "<string>", line 1, in connect
TypeError: coercing to Unicode: need string or buffer, instance found

This is the section of code that reads the XML file:

ConfigDom = parse(TestSettingsStore.ConfigFileName)
#ConfigDom
TSSElList =
ConfigDom.getElementsByTagName("TargetSocketSettin gs")
NumTargSocks = len(TSSElList)
if NumTargSocks > 0:
TargetIPAddrList =
TSSElList[0].getElementsByTagName("TargetIPAddr")
TargetIPPortList =
TSSElList[0].getElementsByTagName("TargetIPPort")
AddrListLen = len(TargetIPAddrList)
PortListLen = len(TargetIPPortList)
if AddrListLen > 0 and PortListLen > 0:
if TargetIPAddrList[0] <> "" and TargetIPPortList[0] <>
0:
StillNeedSettings = False

TestSettingsStore.SettingsDictionary['TargetIPAddr'] =
TargetIPAddrList[0]

TestSettingsStore.SettingsDictionary['TargetIPPort'] =
TargetIPPortList[0]

This I saved as Unicode from Notepad with encoding UTF-16:
<?xml version="1.0" encoding="UTF-16" ?>
<TargetSocketSettings>
<TargetIPAddr>127.0.0.1</TargetIPAddr>
<TargetIPPort>43210</TargetIPPort>
</TargetSocketSettings>

this I saved as UTF-8 from Notepad with encoding UTF-8:
<?xml version="1.0" encoding="UTF-16" ?>
<TargetSocketSettings>
<TargetIPAddr>127.0.0.1</TargetIPAddr>
<TargetIPPort>43210</TargetIPPort>
</TargetSocketSettings>

Both formats create the same error.

I'm probably doing something dumb as I've never done XML in Python
before. Any ideas what?


Ben Cartwright 03-22-2006 02:17 AM

Re: TypeError coercing to Unicode with field read from XML file
 
Randall Parker wrote:
> My problem is that once I parse the file with minidom and a field from
> it to another variable as shown with this line:
> IPAddr = self.SocketSettingsObj.IPAddress
>
> I get this error:

[...]
> if TargetIPAddrList[0] <> "" and TargetIPPortList[0] <>
> 0:
> StillNeedSettings = False
>
> TestSettingsStore.SettingsDictionary['TargetIPAddr'] =
> TargetIPAddrList[0]
>
> TestSettingsStore.SettingsDictionary['TargetIPPort'] =
> TargetIPPortList[0]



TargetIPAddrList[0] and TargetIPPortList[0] are *not* a string and an
int, respectively. They're both DOM elements. If you want an int, you
have to explicitly cast the variable as an int. Type matters in
Python:

>>> '0' == 0

False

Back to your code: try a couple debugging print statements to see
exactly what your variables are. The built-in type() function should
help.

To fix the problem, you need to dig a little deeper in the DOM, e.g.:

addr = TargetIPAddrList[0].firstChild.nodeValue
try:
port = int(TargetIPPortList[0].firstChild.nodeValue)
except ValueError: # safely handle invalid strings for int
port = 0
if addr and port:
StillNeedSettings = False
TestSettingsStore.SettingsDictionary['TargetIPAddr'] = addr
TestSettingsStore.SettingsDictionary['TargetIPPort'] = port

--Ben


Fredrik Lundh 03-22-2006 08:09 AM

Re: TypeError coercing to Unicode with field read from XML file
 
Randall Parker wrote:

> I'm probably doing something dumb as I've never done XML in Python
> before. Any ideas what?


using minidom ? ;-)

if you're not wedded to minidom, there are alternatives that are easier
to use for things like this. here's an ElementTree version of your code:

ConfigTree = ET.parse(TestSettingsStore.ConfigFileName)
# ConfigTree represents the TargetSocketSettings root element

TargetIPAddr = tree.findtext("TargetIPAddr")
TargetIPPort = tree.findtext("TargetIPPort")

if TargetIPAddr and TargetIPPort:
StillNeedSettings = False
TestSettingsStore.SettingsDictionary["TargetIPAddr"] = TargetIPAddr
TestSettingsStore.SettingsDictionary["TargetIPPort"] = TargetIPPort

where ET is set by something like:

try:
import xml.etree.ElementTree as ET # Python 2.5
except ImportError:
# http://effbot.org/zone/element-index.htm
import elementtree.ElementTree as ET

if you don't want to ship the entire ElementTree library with your app,
you can just add the ElementTree.py module somewhere, and do e.g.

import myapp.utils.ElementTree as ET

:::

if you plan to grab more stuff from XML files, you might wish to apply the
DRY principle (google it!), and use a little helper to copy the variables from
the XML file to your dictionary:

def getconfig(settings, elem, keys):
d = {}
for key in keys:
value = elem.findtext(key)
if not value:
return False
d[key] = value
# only update the settings dict if all keys were present
settings.update(d)
return True

if getconfig(
TestSettingsStore.SettingsDictionary,
ConfigTree,
("TargetIPAddr", "TargetIPPortX")):
StillNeedSettings = False

</F>





All times are GMT. The time now is 11:32 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.