在PyObjC中将NSDictionary转换为plist字符串,而不是将其写入文件

时间:2013-07-13 01:56:29

标签: python plist nsdictionary foundation pyobjc

公平警告:我完全不知道Objective-C。我正在使用PyObjC的Foundation模块。

我有一个字典,用于创建NSDictionary。一个例子:

from Foundation import NSDictionary
d = {'a': 1, 'b': 2, 'c': 3}
nsd = NSDictionary(d)

我知道我可以将nsd的内容写入nsd.writeToFile_atomically_()的文件中,但我无法弄清楚如何获取包含所有plist-y XML的字符串。您可能认为我可以使用StringIO对象,但是:

>>> import StringIO
>>> s = StringIO.StringIO()
>>> nsd.writeToFile_atomically_(s,True)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: NSInvalidArgumentException - Class OC_PythonObject: no such selector: getFileSystemRepresentation:maxLength:

我不能在帮助页面上做出正面或反面,我已经尝试过搜索SO和网络,人们似乎对我正在尝试做的事情更感兴趣。

我希望能够做到这样的事情:

plst = nsd.asPlistyString_()

或许我必须使用NSSString,我不知道:

plst = NSString.makePlistyStringFromDictionary_(nsd)

无论哪种方式,plst都会像"<?xml version="1.0" encoding="UTF-8"?>\n<!DOCTYPE plist PUBLIC" yada yada。有人能指出我正确的方向吗?

编辑:我知道plistlib但我正在尝试直接与基金会这样做,以帮助我的代码未来兼容。 (plistlib非常好。)

2 个答案:

答案 0 :(得分:3)

虽然这不能直接回答您的问题,但您可以使用标准库模块plistlib更轻松地完成此操作:

import plistlib
d = {'a': 1, 'b': 2, 'c': 3}
plist_string = plistlib.writePlistToString(d)

结果:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>a</key>
    <integer>1</integer>
    <key>b</key>
    <integer>2</integer>
    <key>c</key>
    <integer>3</integer>
</dict>
</plist>

答案 1 :(得分:1)

这样的事情对你有用。您基本上需要使用NSPropertyListSerialization将字典序列化为xml。

from Foundation import NSDictionary, NSString, NSPropertyListSerialization
from Foundation import NSUTF8StringEncoding, NSPropertyListXMLFormat_v1_0

d = {'a': 1, 'b': 2, 'c': 3}
nsd = NSDictionary(d)

# serialize the dictionary as XML into an NSData object
xml_plist_data, error = NSPropertyListSerialization.dataWithPropertyList_format_options_error_(nsd, NSPropertyListXMLFormat_v1_0, 0, None)

if xml_plist_data:
    # convert that data to a string
    xml_plist = NSString.alloc().initWithData_encoding_(xml_plist_data, NSUTF8StringEncoding)
else:
    # look at the error
    pass