首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何从InputStream中删除重音字符

如何从InputStream中删除重音字符
EN

Stack Overflow用户
提问于 2010-05-18 17:29:13
回答 5查看 4.5K关注 0票数 5

我正在尝试使用拉式解析器解析Android上的Rss2.0提要。

代码语言:javascript
复制
XmlPullParser parser = Xml.newPullParser();
parser.setInput(url.open(), null);

提要XML的prolog表示编码为"utf-8“。当我打开远程流并将其传递给我的Pull Parser时,我得到了无效的令牌,文档格式不正确的异常。

当我保存XML文件并在浏览器(FireFox)中打开它时,浏览器报告存在Unicode0x12字符(重音?)文件中,并且无法呈现XML。

假设我对返回的XML没有任何控制,那么处理这种情况的最佳方法是什么?

谢谢。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2010-05-25 04:28:15

你在哪里发现0x12是严肃的口音?UTF-8的字符范围为0x00-0x7F,编码方式与ASCII码相同,ASCII码位0x12是控制字符、DC2或CTRL+R。

这听起来像是某种编码问题。解决这个问题的最简单方法是查看保存在十六进制编辑器中的文件。有一些事情需要检查:

  1. 开头的字节顺序标记可能会让一些XML解析器
  2. 感到困惑,即使XML声明说编码是UTF-8,它实际上可能没有这种编码,并且文件将被解码,所有unicode字符在XML中都是合法的,这就是为什么火狐拒绝呈现它。特别是,XML规范规定0x9、0xA和0xD是唯一小于0x20的有效字符,因此0x12肯定会导致兼容的解析器发出抱怨。

如果您可以将文件上传到pastebin或类似的文件,我可以帮助找到原因并提出解决方案。

编辑: Ok,你不能上传。这是可以理解的。

您得到的XML不知何故被损坏了,理想的做法是联系负责生成它的一方,看看问题是否可以解决。

在这样做之前,有一件事需要检查--你确定你的数据不会被干扰吗?某些形式的通信(短信息)仅允许7位字符。这将变成0x92 (ASCII向前滴答/撇号-严重重音?)转换为0x12。这看起来很巧合,特别是如果这些出现在文件中,其中可能会有一个重音。

否则,你将不得不尽可能地利用你所拥有的:

  1. 虽然不是严格必要的,但它是防御性的,并将"UTF-8“作为第二个参数传递给setInput,在parser.
  2. similarly,上,通过将不同的编码作为第二个参数传递,强制解析器使用另一种字符编码。除了"UTF-8“之外,要尝试的编码是"iso-8859-1”和"UTF-16“。Sun site上提供了java支持的编码的完整列表-您可以尝试所有这些编码。(我找不到一个明确的Android支持的编码列表。)
  3. 作为最后的手段,你可以去掉无效的字符,例如删除所有0x20以下的非空格字符(0x9,0xA和0xD都是空格)。如果移除它们很困难,您可以替换它们。

例如

代码语言:javascript
复制
class ReplacingInputStream extends FilterInputStream
{
   public int read() throws IOException
   {
      int read = super.read();
      if (read!=-1 && read<0x20 && !(read==0x9 || read==0xA || read==0xB))
         read = 0x20;
      return read;          
   }
}

您可以将它包装在现有的输入流中,它会过滤掉无效的字符。请注意,您可能很容易对XML造成更大的破坏,或者最终得到毫无意义的XML,但同样,它可能允许您提取所需的数据,或者更容易地看到问题所在。

票数 6
EN

Stack Overflow用户

发布于 2010-05-24 12:44:54

我使用正则表达式对其进行过滤,但技巧不是尝试获取和替换重音。这取决于编码,并且您不想更改内容。

尝试将标签的内容插入到此标签中

像这样

代码语言:javascript
复制
<title>My title</title>
<link>http://mylink.com</link>
<description>My description</description>

到这个

代码语言:javascript
复制
<title><![CDATA[My title]]></title>
<link><![CDATA[http://milynk.com]]></link>
<description><![CDATA[My Description]]></description>

正则表达式应该不是很难理解。它对我很有效,希望对你有帮助。

票数 2
EN

Stack Overflow用户

发布于 2010-05-27 21:39:46

UTF-8的问题在于它是多字节编码。因此,它需要一种方法来指示字符何时由一个以上的字节组成(可能是两个、三个、四个……)。这样做的方法是通过保留一些字节值来表示多字节字符。因此,编码遵循一些基本规则:

  • 单字节字符没有最大有效位设置(代码兼容7位ASCII码)。
  • 双字节字符按顺序表示: 110xxxxx 10xxxxx
  • 三字节: 1110xxxx 10xxxxx
  • 四字节: 11110xxx 10xxxxx 10xxxxx 10xxxxx

<代码>F29

您的问题是,您可能正在读取一些应该以UTF-8进行编码的字符串(正如编码定义所述),但是字节块可能并不是真正以UTF-8编码的(声明为UTF-8,但是使用不同的编码方式,如Cp1252对文本进行编码,这是一个常见的错误)。您的XML解析器试图将字节块解释为UTF-8字符,但是发现了一些不符合编码规则的东西(非法字符)。即设置了两个最高有效字节的两个字节将带来非法编码错误: 110xxxxx必须总是跟在10xxxxxx之后(诸如01xxxxxxx11xxxxx00xxxxxx的值将是非法的)。

当使用非可变长度编码时,不会出现此问题。也就是说,如果您在XML声明中声明您的文件使用Windows-1252编码,但您最终使用的是ANSI,那么唯一的问题将是非ASCII字符(值> 127)将不能正确呈现。

解决方案:

  1. 尝试通过其他方式检测编码。
    • 如果你总是从同一个源读取数据,你可以对一些文件进行采样,并使用一个高级的文本编辑器来尝试推断出文件的实际编码(如notepad++jEdit等)。
    • 通过编程来做到这一点。在执行任何实际的xml processing.

之前对原始字节进行预处理。

  1. 在XML processor

上强制执行实际的编码

或者,如果您不介意非ASCII字符(不管是否偶尔出现奇怪的符号),您可以直接转到步骤2,强制XML处理到任何ASCII兼容的8字节固定长度编码 (ANSI,任何Windows-XXXX代码页,Mac-罗马编码等)。使用您当前的代码,您可以尝试:

代码语言:javascript
复制
XmlPullParser parser = Xml.newPullParser();
parser.setInput(url.open(), "ISO-8859-1");
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2855959

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档