XML::Writer は、US-ASCII と UTF-8 以外はサポートしていません (ENCODING
コンストラクタ引数のドキュメントに記載されています)。XML::Writer を使用して UCS-2be XML ドキュメントを作成するのは難しいですが、不可能ではありません。
use XML::Writer qw( );
# XML::Writer doesn't encode for you, so we need to use :encoding.
# The :raw avoids a problem with CRLF conversion on Windows.
open(my $fh, '>:raw:encoding(UCS-2be)', $qfn)
or die("Can't create \"$qfn\": $!\n");
# This prints the BOM. It's optional, but it's useful when using an
# encoding that's not a superset of US-ASCII (such as UCS-2be).
print($fh "\x{FEFF}");
my $writer = XML::Writer->new(
OUTPUT => $fh,
ENCODING => 'US-ASCII', # Use entities for > U+007F
);
$writer->xmlDecl('UCS-2be');
$writer->startTag('root');
$writer->characters("\x{00041}");
$writer->characters("\x{000C9}");
$writer->characters("\x{10000}");
$writer->endTag();
$writer->end();
欠点: U+007F より上の文字はすべて XML エンティティとして表示されます。上記の例では、
- U+00041 は "
A
" ( 00 41
) として表示されます。良い。
- U+000C9 は "
É
" ( 00 26 00 23 00 78 00 43 00 39 00 3B
) として表示されます。最適ではありませんが、大丈夫です。
- U+10000 は "
𐀀
" ( 00 26 00 23 00 78 00 31 00 30 00 30 00 30 00 30 00 3B
) として表示されます。U+10000 を で格納するには、XML エンティティが必要ですUCB-2e
。
U+FFFF を超える文字がライターに提供されないことを保証できる場合にのみ、上記の欠点を回避できます。
use XML::Writer qw( );
# XML::Writer doesn't encode for you, so we need to use :encoding.
# The :raw avoids a problem with CRLF conversion on Windows.
open(my $fh, '>:raw:encoding(UCS-2be)', $qfn)
or die("Can't create \"$qfn\": $!\n");
# This prints the BOM. It's optional, but it's useful when using an
# encoding that's not a superset of US-ASCII (such as UCS-2be).
print($fh "\x{FEFF}");
my $writer = XML::Writer->new(
OUTPUT => $fh,
ENCODING => 'UTF-8', # Don't use entities.
);
$writer->xmlDecl('UCS-2be');
$writer->startTag('root');
$writer->characters("\x{00041}");
$writer->characters("\x{000C9}");
#$writer->characters("\x{10000}"); # This causes a fatal error
$writer->endTag();
$writer->end();
- U+00041 は "
A
" ( 00 41
) として表示されます。良い。
- U+000C9 は "
É
" ( 00 C9
) として表示されます。良い。
- U+10000 は致命的なエラーを引き起こします。
そして、マイナス面なしでそれを行う方法は次のとおりです。
use Encode qw( decode encode );
use XML::Writer qw( );
my $xml;
{
# XML::Writer doesn't encode for you, so we need to use :encoding.
open(my $fh, '>:encoding(UTF-8)', \$xml);
# This prints the BOM. It's optional, but it's useful when using an
# encoding that's not a superset of US-ASCII (such as UCS-2be).
print($fh "\x{FEFF}");
my $writer = XML::Writer->new(
OUTPUT => $fh,
ENCODING => 'UTF-8', # Don't use entities.
);
$writer->xmlDecl('UCS-2be');
$writer->startTag('root');
$writer->characters("\x{00041}");
$writer->characters("\x{000C9}");
$writer->characters("\x{10000}");
$writer->endTag();
$writer->end();
close($fh);
}
# Fix encoding.
$xml = decode('UTF-8', $xml);
$xml =~ s/([^\x{0000}-\x{FFFF}])/ sprintf('&#x%X;', ord($1)) /eg;
$xml = encode('UCS-2be', $xml);
open(my $fh, '>:raw', $qfn)
or die("Can't create \"$qfn\": $!\n");
print($fh $xml);
- U+00041 は "
A
" ( 00 41
) として表示されます。良い。
- U+000C9 は "
É
" ( 00 C9
) として表示されます。良い。
- U+10000 は "
𐀀
" ( 00 26 00 23 00 78 00 31 00 30 00 30 00 30 00 30 00 3B
) として表示されます。U+10000 を で格納するには、XML エンティティが必要ですUCB-2e
。