哪种XML编码用于存储文件名?



我想在XML文档中存储原始文件名,但是编码不允许。

下面是如何使用shell生成test.xml:

#!/bin/sh
cat <<EOF > test.xml
<?xml version="1.0" encoding="UTF-8"?>
<root>
<music>🎵</music>
<file><![CDATA[$(printf \xf1.mp3)]]></file>
</root>
EOF

现在,如果我尝试用任何XML解析器(例如python)读取它:

import xml.dom.minidom
xml.dom.minidom.parse('test.xml')

我得到编码问题:

xml.parsers.expat.ExpatError: not well-formed (invalid token): line 4, column 19

是否有一种方法使XML允许任何字节(但NUL)?

看起来像编码问题tmp.xml:4: parser error : Input is not proper UTF-8, indicate encoding ! Bytes: 0xF1 0x2E 0x6D 0x70 <file><![CDATA[�.mp3]]></file>。因此printf xf1创建一个非utf8字符。

将ISO-8859-1文件名转换为UTF-8

cat <<EOF > tmp.xml
<?xml version="1.0" encoding="UTF-8"?>
<root>
<music>🎵</music>
<file><![CDATA[$(printf \xf1.mp3 | iconv -f iso-8859-1 -t utf-8)]]></file>
</root>
EOF

结果

<?xml version="1.0" encoding="UTF-8"?>
<root>
<music>🎵</music>
<file><![CDATA[ñ.mp3]]></file>
</root>

如果源编码未知,则可以存储base64字符串。

printf \xf1.mp3 | base64
8S5tcDM=

改变XML的编码没有错误

cat <<EOF > tmp.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<root>
<music>🎵</music>
<file><![CDATA[$(printf \xf1.mp3)]]></file>
</root>
EOF

xmllint测试

xmllint tmp.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<root>
<music>🎵</music>
<file><![CDATA[�.mp3]]></file>
</root>

显示一个问号,因为它是一个utf-8控制台打印ISO-8859-1文本。

你似乎混淆了两个独立的问题:

(a)字符库。XML 1.0可以包括

集合中的任何字符
#x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]

如果你想保存该范围之外的数据(通常是二进制数据)(例如NUL, #x0),你需要找到一些将二进制数据表示为字符的方法;最常见的选择是Base64。

(b)编码。上面允许的字符列表是根据Unicode码点定义的。但是有不同的方式来表示(编码)这些码点作为二进制八字节。您需要确保实际使用的编码是正确声明的:如果文件说它是UTF-8,那么它实际上必须是UTF-8。

相关内容

  • 没有找到相关文章

最新更新