我遇到了这样的问题:我的 XML 解析器 (VTD-XML) 似乎无法处理 Unicode 补充字符(如果我在这里已经错了,请更正)。看起来,解析器只使用这些字符的低 16 位。
我无法切换到我正在处理的项目中的另一个解析器。我正在解析 Medline 摘要(https://www.ncbi.nlm.nih.gov/pubmed https://www.ncbi.nlm.nih.gov/pubmed)并且去年似乎添加了包含补充字符的文档(例如https://www.ncbi.nlm.nih.gov/pubmed/?term=26855708 https://www.ncbi.nlm.nih.gov/pubmed/?term=26855708,结果部分结束)。
作为一个快速而肮脏的修复,我只是从文档中删除 0xFFFF 以上的所有字符。显然,这会破坏文档文本中的一些表达式,因此我对该解决方案并不满意。
由于我无法更改解析器,我想知道是否存在将补充字符映射到 BMP 中可能具有相似外观字形(如果存在)的字符的可能性。
当然我欢迎任何其他想法。甚至可以用某种占位符替换补充字符,然后将原始字符放回原处,但这似乎很容易出错。更好的想法?
编辑:这里有一些 - 希望 - 最小的例子来说明这个问题是如何与 VTD-XML 一起出现的:
@Test
public void parseUnicodeBeyondBMP() throws NavException, FileNotFoundException, IOException, EncodingException, EOFException, EntityException, ParseException {
// character codpoint 0x10400
String unicode = "<supplementary>\uD801\uDC00</supplementary>";
byte[] unicodeBytes = unicode.getBytes();
assertEquals(unicode, new String(unicodeBytes, "UTF-8"));
VTDGen vg = new VTDGen();
vg.setDoc(unicodeBytes);
vg.parse(false);
VTDNav vn = vg.getNav();
long fragment = vn.getContentFragment();
int offset = (int) fragment;
int length = (int) (fragment >> 32);
String originalBytePortion = new String(Arrays.copyOfRange(unicodeBytes, offset, offset+length));
String vtdString = vn.toRawString(offset, length);
// this actually succeeds
assertEquals("\uD801\uDC00", originalBytePortion);
// this fails ;-( the returned character is Ѐ, codepoint 0x400, thus the high surrogate is missing
assertEquals("\uD801\uDC00", vtdString);
}