АллегроГраф - символы UTF-8 в N-триплетах
Когда я использую AllegroGraph 4.6 Python API, я могу использовать метод connection.addTriple(), чтобы попытаться добавить тройку, заканчивающуюся литералом, содержащим символ Юникода (×):
conn.addTriple( ..., ..., '5 × 10**5' )
Это не работает Я получаю ошибку:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position...
Вот полный трекбек:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/cygdrive/c/agraph-4.6-client-python/src2/franz/openrdf/repository/repositoryconnection.py", line 357, in addTriple
self._convert_term_to_mini_term(obj), cxt)
File "/cygdrive/c/agraph-4.6-client-python/src2/franz/openrdf/repository/repositoryconnection.py", line 235, in _convert_term_to_mini_term
return self._to_ntriples(term)
File "/cygdrive/c/agraph-4.6-client-python/src2/franz/openrdf/repository/repositoryconnection.py", line 367, in _to_ntriples
else: return term.toNTriples();
File "/cygdrive/c/agraph-4.6-client-python/src2/franz/openrdf/model/literal.py", line 182, in toNTriples
sb.append(strings.encode_ntriple_string(self.getLabel()))
File "/cygdrive/c/agraph-4.6-client-python/src2/franz/openrdf/util/strings.py", line 52, in encode_ntriple_string
string = unicode(string)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 18: ordinal not in range(128)
Вместо этого я могу добавить тройку следующим образом:
conn.addTriple( ..., ..., u'5 × 10**5' )
Таким образом, я не получаю ошибку.
Но если я загружу файл с ntriples, который содержит некоторые символы в кодировке UTF-8, используя connection.addFile(filename, format=RDFFormat.NTRIPLES)
, Я получаю это сообщение об ошибке, если файл ntriples сохранен как кодировка ANSI из Notepad++:
400 MALFORMED DATA: N-Triples parser error while parsing
#<http request stream @ #x10046f9ea2> at line 12764 (last character was
#\×): nil
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/cygdrive/c/agraph-4.6-client-python/src2/franz/openrdf/repository/repositoryconnection.py", line 341, in addFile
commitEvery=self.add_commit_size)
File "/cygdrive/c/agraph-4.6-client-python/src2/franz/miniclient/repository.py", line 342, in loadFile
nullRequest(self, "POST", "/statements?" + params, body, contentType=mime)
File "/cygdrive/c/agraph-4.6-client-python/src2/franz/miniclient/request.py", line 198, in nullRequest
if (status < 200 or status > 204): raise RequestError(status, body)
franz.miniclient.request.RequestError: Server returned 400: N-Triples parser error while parsing
Я получаю это сообщение об ошибке, если файл сохраняется в кодировке UTF-8:
400 MALFORMED DATA: N-Triples parser error while parsing
#<http request stream @ #x100486e8b2> at line 1 (last character was
#\): Subjects must be resources (i.e., URIs or blank nodes)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/cygdrive/c/agraph-4.6-client-python/src2/franz/openrdf/repository/repositoryconnection.py", line 341, in addFile
commitEvery=self.add_commit_size)
File "/cygdrive/c/agraph-4.6-client-python/src2/franz/miniclient/repository.py", line 342, in loadFile
nullRequest(self, "POST", "/statements?" + params, body, contentType=mime)
File "/cygdrive/c/agraph-4.6-client-python/src2/franz/miniclient/request.py", line 198, in nullRequest
if (status < 200 or status > 204): raise RequestError(status, body)
franz.miniclient.request.RequestError: Server returned 400: N-Triples parser error while parsing
Однако, если для файла задана кодировка ANSI в Notepad++, я могу зайти и вставить ×
символ, сохранить, а затем файл загружается нормально. Или, если я изменю кодировку файла на UTF-8 после вставки символа, то символ изменится на какой-то странный символ xD7. Если для файла задана кодировка UTF-8, и я вставляю ×
там, то если я изменю кодировку на ANSI ×
изменения в ×
,
Когда файл был передан мне, он имел ×
где ×
должно было быть, и когда я попытался загрузить его в AllegroGraph, я получил первую ошибку 400 MALFORMED DATA, которая вылетает в строке, где символ фактически появляется в файле (12764), а не только в первой строке. Я предполагаю, что причина, по которой я получаю вторую ошибку 400 MALFORMED DATA в строке 1, связана с заголовком, написанным Notepad ++ для файлов в кодировке UTF-8. Очевидно, я должен сохранить файл как ANSI, если я хочу, чтобы AllegroGraph не сразу икнул, но должен быть какой-то способ сказать AllegroGraph читать такие вещи, как ×
как символы UTF-8.
В файле тройка выглядит так:
<...some subject URI...> <...some predicate URI...> "5 × 10**5" .
2 ответа
\xd7
это кодировка Latin-1 ×
,
×
это то, что вы получите, если ошибочно расшифруете ×
в cp1252 (часто кодек Windows по умолчанию), если он был закодирован в UTF-8.
Когда вам дают файлы, которые показывают ×
попробуйте изменить кодек, который используется для их отображения, на UTF-8.
Обзор Unicode в Python смотрите здесь. ~ Благодаря Дениту.
Как вы узнали из поддержки AllegroGraph:
AllegroGraph может принимать символы Юникода в nTriples, используя обозначение \uXXXX. В качестве альтернативы можно использовать RDFXML, который позволяет оставить символы Юникода такими, как они есть.
Использовать модуль кодеков.
import codecs
f = codecs.open('file.txt','r','utf8')
это откроет ваш файл форсируя кодировку utf8