【问题标题】:AllegroGraph - UTF-8 characters in N-TriplesAllegroGraph - N-Triples 中的 UTF-8 字符
【发布时间】:2012-06-14 17:51:12
【问题描述】:

当我使用 AllegroGraph 4.6 Python API 时,我可以使用 connection.addTriple() 方法尝试添加以包含 unicode 字符 (×) 的文字结尾的三元组:

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' )

这样我就不会出错了。

但是,如果我使用 connection.addFile(filename, format=RDFFormat.NTRIPLES) 加载包含一些 UTF-8 编码字符的 ntriples 文件,如果 ntriples 文件从 Notepad++ 保存为 ANSI 编码,我会收到此错误消息:

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

但是,如果文件在 Notepad++ 中设置为 ANSI 编码,我可以进入并粘贴 × 字符,保存,然后文件加载正常。或者,如果我在粘贴字符后将文件编码更改为 UTF-8,则该字符会变为一些奇怪的 xD7 字符。如果文件设置为 UTF-8 编码并且我将× 粘贴在那里,那么如果我将编码更改为 ANSI,× 将更改为×

当文件给我时,它有 × 应该是 ×,当我尝试在 AllegroGraph 中加载它时,我得到了第一个 400 MALFORMED DATA 错误,该错误在字符实际上出现在文件 (12764) 中,而不仅仅是在第一行。我认为我在第 1 行收到第二个 400 MALFORMED DATA 错误的原因与 Notepad++ 为 UTF-8 编码文件编写的标头有关。显然,如果我想让 AllegroGraph 不立即打嗝,我必须将文件另存为 ANSI,但必须有某种方法告诉 AllegroGraph 将 × 之类的内容读取为 UTF-8 字符。

在文件中,三元组看起来像:

&lt;...some subject URI...&gt; &lt;...some predicate URI...&gt; "5 × 10**5" .

【问题讨论】:

  • 你用什么代码添加ntriples的文件?
  • @deadly connection.addFile(filename, format=RDFFormat.NTRIPLES)
  • 奇怪。我可以理解为什么 addTriple 会出错,但是使用 addFile 你只是给它文件名,它应该会愉快地解析文件。完整的追溯是什么?
  • @deadly 我原来的问题实际上犯了一个错误。加载文件时,我没有收到相同的错误消息。查看我添加的回溯。
  • 看这个:bit.ly/unipain

标签: python unicode utf-8 allegrograph


【解决方案1】:

使用编解码器模块。

import codecs
f = codecs.open('file.txt','r','utf8')

这将打开您的文件,强制使用 utf8 编码

【讨论】:

  • addFile 方法采用文件名字符串而不是文件对象,但我想我可以尝试编辑 AllegroGraph Python API 看看这是否有效。
  • 我编辑了 API 来执行此操作,但我仍然收到 400 MALFORMED DATA 错误。
  • @JohnPeterThompsonGarcés 我不知道您正在处理的 API,但是您不能打开文件然后遍历其内容吗?类似于:f = codecs.open('file.txt','r','utf8') for line in f.readlines(): conn.addTriple( ..., ..., line ) 如果需要,您甚至可以在 line 变量周围包装一个 unicode 函数,例如:conn.addTriple( ..., ..., unicode(line,'utf8') )
【解决方案2】:

\xd7× 的Latin-1 编码。

× 是如果您错误地将 × 解码为 cp1252(通常是 Windows 的默认编解码器),如果它是用 UTF-8 编码的。

当您收到显示 × 的文件时,请尝试将用于显示它们的编解码器更改为 UTF-8。


有关 Python 中 Unicode 的概述,请参阅here。 ~ 感谢丹妮丝。


正如您从 AllegroGraph 支持中发现的那样:

AllegroGraph 可以使用 \uXXXX 在 nTriples 中获取 unicode 字符 符号。或者,可以使用 RDFXML,它允许您离开 Unicode 字符。

【讨论】:

  • addFile() 仍然存在问题。如果文件以 UTF-8 编码,我会得到一个 400 MALFORMED DATA 并且解析器在 position 1 处失败。即使我按照 Justin.Wood 的建议并使用 f = codecs.open(...,'r','utf8'),它也会失败。如果我给它一些带有 ANSI 编码的东西,它不会在 position 1 失败,但如果它包含 ×(如它在 ANSI 编码下的 Notepad++ 中出现的那样),那么它将在字符的位置失败。如果它是 ANSI 编码并且粘贴了 × 的 Latin-1 编码,它不会失败,但这不是一个好的解决方案,因为我有多个 utf8 字符的文件。
猜你喜欢
  • 2017-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-12
  • 2012-01-14
  • 1970-01-01
相关资源
最近更新 更多