Проблемы при добавлении содержимого xml с символами UTF-8 в коллекцию eXist-db с использованием Perl

Я пытаюсь добавить динамически сгенерированный XML-контент в коллекцию eXist-db (см. код ниже addFile.pl) с помощью Perl, проблема в том, что всякий раз, когда контент содержит символы UTF-8, я получаю сообщение об ошибке Failed to parse XML-RPC request: Byte "195" is not a member of the (7-bit) ASCII character set..

#!/usr/bin/perl
use RPC::XML;
use RPC::XML::Client;

my ($sec, $min, $hour, $mday, $mon, $year) = localtime();
my $timestamp = sprintf("%04d%02d%02d%02d%02d%02d",$year+1900,$mon+1,$mday,$hour,$min,$sec);
print("Timestamp: $timestamp\n");

my $FILENAME = "$timestamp.xml";
my $COLLECTION = 'output';

my $record = <<END;
<document id="doc_20150419014112">
  <text>ñáéíóú</text>
</document>
END

$query = <<END;
xquery version "3.0";
import module namespace xmldb="http://exist-db.org/xquery/xmldb";
declare variable \$filename := '$FILENAME';
declare variable \$record := '';

let \$log-in := xmldb:login("/db", "admin", "admin")
(: let \$create-collection := xmldb:create-collection("/db", "$COLLECTION") :)
let \$record := 
$record

for \$target in ('/db/$COLLECTION')
  return xmldb:store(\$target, \$filename, \$record)
END

print $query;

$URL = "http://admin:admin\@localhost:8080/exist/xmlrpc";
# connecting to $URL...
$client = new RPC::XML::Client $URL;
# Output options
$options = RPC::XML::struct->new(
    'indent' => 'yes', 
    'encoding' => 'UTF-8',
    'highlight-matches' => 'none');
$req = RPC::XML::request->new("query", $query, 20, 1, $options);
$response = $client->send_request($req);
if($response->is_fault) {
    die "An error occurred: " . $response->string . "\n";
}
my $result = $response->value;
print $result;

Когда я запускаю скрипт xquery (см. ниже) непосредственно с помощью eXide, он работает нормально, но когда я запускаю его через скрипт perl, я получаю следующее:

$ perl addFile.pl 

Timestamp: 20150428162016
xquery version "3.0";
import module namespace xmldb="http://exist-db.org/xquery/xmldb";
declare variable $filename := '20150428162016.xml';
declare variable $record := '';

let $log-in := xmldb:login("/db", "admin", "admin")
(: let $create-collection := xmldb:create-collection("/db", "output") :)
let $record := 
<document id="doc_20150419014112">
  <text>ñáéíóú</text>
</document>


for $target in ('/db/output')
  return xmldb:store($target, $filename, $record)
An error occurred: Failed to parse XML-RPC request: Byte "195" is not a member of the (7-bit) ASCII character set.

person richardtk_1    schedule 28.04.2015    source источник
comment
Ну, во-первых, вам нужно use utf8 в вашем скрипте, потому что вы вводите расширенные символы непосредственно в скрипт. Это гарантирует, что встроенная строка ñáéíóú на самом деле закодирована в UTF-8.   -  person Sinan Ünür    schedule 29.04.2015
comment
Кроме того, пожалуйста, прекратите использовать косвенную запись объекта. Например, вместо new RPC::XML::Client напишите RPC::XML::Client->new и т. д. Perl — это не Java.   -  person Sinan Ünür    schedule 29.04.2015
comment
Я уже пробовал «использовать utf8», не работает.   -  person richardtk_1    schedule 29.04.2015
comment
Использование utf8 в исходном коде, который включает строковые литералы UTF-8, является необходимым условием, а не достаточным. Также убедитесь, что вы действительно сохранили файл в кодировке UTF-8. Опять же, это необходимое условие, прежде чем кому-либо следует тратить время на дальнейшее изучение этого вопроса. Очевидно, база данных по какой-то причине ожидает от вас 7-битный ASCII.   -  person Sinan Ünür    schedule 29.04.2015
comment
Тоже проверил, проблема не в этом.   -  person richardtk_1    schedule 29.04.2015
comment
Мне кажется, что проблема возникла еще до того, как вы поговорите с eXist. eXist вполне доволен данными UTF-8. Знает ли ваш клиент XML-RPC, что вы используете UTF-8, и доволен ли он этим? Я думаю, что ваша ошибка может быть связана с используемой вами библиотекой XML:RPC, а не с eXist.   -  person adamretter    schedule 29.04.2015
comment
Вы были правы, @adamretter, я нашел решение и разместил его ниже, спасибо.   -  person richardtk_1    schedule 29.04.2015


Ответы (1)


Я нашел решение здесь, я приведу ответ только в кейс:

Модуль Perl RPC::XML по умолчанию использует us-ascii в качестве кодировки XML. Если вы доставляете содержимое UTF-8 из базы данных или других источников, RPC::XML создает недопустимый XML с настройкой по умолчанию.

Кодировку XML, используемую RPC::XML, можно изменить только глобально:

#!/usr/bin/perl
use RPC::XML;
use RPC::XML::Client;
$RPC::XML::ENCODING = 'utf-8';
person richardtk_1    schedule 29.04.2015