0

我正在使用 plistib 阅读 iTunes 生成的 xml 播放列表。xml 有一个 utf8 标头。

当我使用 plistib 读取 xml 时,我得到了 unicode(例如,'Name': u'Don\u2019t You Remember')和字节字符串(例如,'Name': 'Where Eagles Dare')。

标准建议是尽快使用正确的编码解码您阅读的内容,并在程序中使用 unicode。然而,

unicode_string.decode('utf8') 

失败(因为它应该)

UnicodeEncodeError: 'ascii' codec can't encode character u'\u2019' in position 3: ordinal not in range(128)

解决方案似乎是:

for name in names:
    if isinstance(name, str):
        name = name.decode('utf8')
    # etc.

这是处理问题的正确方法吗?有没有更好的办法?

我在Windows 7上。

编辑:

xml 读取:

import plistlib
xml = plistlb.readPlist(fn)
for track in xml['Tracks']:
    info = xml['Tracks'][track]
    info['Name']

闲置生产:

u'Don\u2019t You Remember'
'Where Eagles Dare'

这是xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Major Version</key><integer>1</integer>
    <key>Minor Version</key><integer>1</integer>
    <key>Date</key><date>2013-08-14T15:04:27Z</date>
    <key>Application Version</key><string>10.6.3</string>
    <key>Features</key><integer>5</integer>
    <key>Show Content Ratings</key><true/>
    <key>Music Folder</key><string>file://localhost/C:/Users/rdp/Music/iTunes/iTunes%20Media/</string>
    <key>Library Persistent ID</key><string>FE28CCACD9A36C34</string>
    <key>Tracks</key>
    <dict>
        <key>1019</key>
        <dict>
            <key>Track ID</key><integer>1019</integer>
            <key>Name</key><string>Where Eagles Dare</string>
            <key>Artist</key><string>Iron Maiden</string>
            <key>Album</key><string>Piece Of Mind</string>
            <key>Genre</key><string>Rock</string>
            <key>Kind</key><string>MPEG audio file</string>
            <key>Size</key><integer>7372755</integer>
            <key>Total Time</key><integer>370128</integer>
            <key>Track Number</key><integer>1</integer>
            <key>Year</key><integer>1983</integer>
            <key>Date Modified</key><date>2009-10-07T21:11:31Z</date>
            <key>Date Added</key><date>2008-02-07T16:04:15Z</date>
            <key>Bit Rate</key><integer>153</integer>
            <key>Sample Rate</key><integer>44100</integer>
            <key>Play Count</key><integer>4</integer>
            <key>Play Date</key><integer>3414416760</integer>
            <key>Play Date UTC</key><date>2012-03-12T21:06:00Z</date>
            <key>Artwork Count</key><integer>1</integer>
            <key>Persistent ID</key><string>FE28CCACD9A383E5</string>
            <key>Track Type</key><string>File</string>
            <key>Location</key><string>file://localhost/D:/music/Iron%20Maiden/Piece%20Of%20Mind/01%20Where%20Eagles%20Dare.mp3</string>
            <key>File Folder Count</key><integer>-1</integer>
            <key>Library Folder Count</key><integer>-1</integer>
        </dict>
        <key>11559</key>
        <dict>
            <key>Track ID</key><integer>11559</integer>
            <key>Name</key><string>Don’t You Remember</string>
            <key>Artist</key><string>Adele</string>
            <key>Album</key><string>21</string>
            <key>Genre</key><string>Pop</string>
            <key>Kind</key><string>MPEG audio file</string>
            <key>Size</key><integer>6120028</integer>
            <key>Total Time</key><integer>229511</integer>
            <key>Track Number</key><integer>4</integer>
            <key>Track Count</key><integer>11</integer>
            <key>Year</key><integer>2011</integer>
            <key>Date Modified</key><date>2012-11-17T10:50:31Z</date>
            <key>Date Added</key><date>2012-12-19T16:03:46Z</date>
            <key>Bit Rate</key><integer>199</integer>
            <key>Sample Rate</key><integer>44100</integer>
            <key>Artwork Count</key><integer>1</integer>
            <key>Persistent ID</key><string>7130C888606FB153</string>
            <key>Track Type</key><string>File</string>
            <key>Location</key><string>file://localhost/D:/music/Adele/21/04%20-%20Don%E2%80%99t%20You%20Remember.mp3</string>
            <key>File Folder Count</key><integer>-1</integer>
            <key>Library Folder Count</key><integer>-1</integer>
        </dict>
    </dict>
    <key>Playlists</key>
    <array>
        <dict>
            <key>Name</key><string>short</string>
            <key>Playlist ID</key><integer>30888</integer>
            <key>Playlist Persistent ID</key><string>166746C6572B0005</string>
            <key>All Items</key><true/>
            <key>Playlist Items</key>
            <array>
                <dict>
                    <key>Track ID</key><integer>11559</integer>
                </dict>
                <dict>
                    <key>Track ID</key><integer>1019</integer>
                </dict>
            </array>
        </dict>
    </array>
</dict>
</plist>
4

1 回答 1

1

哇,这是一个非常奇怪的行为。我什至会说这种不统一的行为是 .x 的 2.X 实现中的一个错误plistlib。Python 3 中的plistlib总是返回更好的 unicode 字符串。

但是你必须忍受它:)所以你的问题的答案是肯定的。读取字符串时应始终保护自己plist

def safe_unicode(s):
    if isinstance(s, unicode):
        return s
    return s.decode('utf-8', errors='replace')

value = safe_unicode(info['Name'])

我添加了errors='replace'以防万一字符串未utf-8编码。\ufffd如果无法解码,您将获得一堆字符。如果您宁愿遇到异常,只需将其保留并使用e.decode('utf-8').

更新:

当我尝试使用 ElementTree 时:

from xml.etree import ElementTree as et
tree = et.parse('test.plist')
map(lambda x: x.text, tree.findall('dict/dict/dict')[1].findall('string'))

这给了我:

[u'Don\u2019t You Remember',
 'Adele',
 '21',
 'Pop',
 'MPEG audio file',
 '7130C888606FB153',
 'File',
 'file://localhost/D:/music/Adele/21/04%20-%20Don%E2%80%99t%20You%20Remember.mp3']

所以有unicode和字节串混合:-/

于 2013-08-16T19:11:26.957 回答