2015-08-07 2 views
4

Следующий код используется для анализа XML-файла. Я заметил, что символ эможи не обрабатывается правильно. В примере вход имеет один emoji в конце (http://www.iemoji.com/view/emoji/693/people/revolving-hearts), символ удваивается на выходе. Это известная ошибка?java xml parser with emoji character

import java.io.File; 
import javax.xml.parsers.DocumentBuilder; 
import javax.xml.parsers.DocumentBuilderFactory; 
import org.w3c.dom.Document; 
import org.w3c.dom.Element; 
import org.w3c.dom.NamedNodeMap; 
import org.w3c.dom.Node; 
import org.w3c.dom.NodeList; 

public class XmlTest { 

    public static void main(String[] args) {    
     DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance(); 
     domFactory.setValidating(false); 
     File file = new File("c:\\temp\\emoji.xml"); 

     try { 
      DocumentBuilder builder = domFactory.newDocumentBuilder(); 
      Document doc = builder.parse(file); 

      NodeList nodes = doc.getElementsByTagName("entry"); 
      Node node = nodes.item(0); 
      NamedNodeMap map = ((Element)node).getAttributes(); 

      for (int i=0; i<map.getLength(); i++) { 
       Node n = map.item(i); 
       System.out.println(); 
       System.out.println(n.getNodeValue()); 

       char[] chars = n.getNodeValue().toCharArray(); 

       for (int j=0; j<chars.length; j++) { 
        System.out.print(chars[j] + ", " + (int)chars[j] + " ");     
       } 
      } 

     } catch (Exception e) {e.printStackTrace(); } 
    } 
} 

Вот вход emoji.xml:

<Attributes> 
    <Map> 
    <entry key="name" value="test"/> 
    </Map> 
</Attributes> 

и выход:

name 
n, 110 a, 97 m, 109 e, 101 
test 
?, 55357 ?, 56478 t, 116 e, 101 s, 115 t, 116 ?, 55357 ?, 56478 ?, 55357 ?, 56478 

ответ

4

я могу воспроизвести проблему с помощью JDK 1.7.

Причиной этой проблемы может быть ошибка в синтаксический анализатор XML, поставляемый с JDK (В этом случае Xerces, расположенные в пакетах com.sun.org.apache.xerces.internal.* в rt.jar)

Символы Emoji являются не в BMP Юникод и поэтому представлены в виде двух символов (высокий и низкий суррогат). Когда парсер сталкивается с этими суррогатами, он обрабатывает их особым образом и проверяет, являются ли они действительным символом XML при преобразовании в дополнительный символ.

Код глючит расположен в XMLScanner.scanAttributeValue в следующем разделе кода

  } else if (c != -1 && XMLChar.isHighSurrogate(c)) { 
       if (scanSurrogates(fStringBuffer3)) { 
        stringBuffer.append(fStringBuffer3); 
        if (entityDepth == fEntityDepth && fNeedNonNormalizedValue) { 
         fStringBuffer2.append(fStringBuffer3); 
        } 

Два символы для Эмодзи обрабатываются в переменный буфере fStringBuffer3, а затем добавляются в буфер для значения атрибута. Проблема в том, что fStringBuffer3 не очищается. При анализе второго символа эможига он все еще содержит старое содержимое, поэтому символы добавляются дважды.

Если вы попытаетесь использовать значение атрибута, содержащее три или более emojis, вы четко видите, как они накапливаются.

+0

Забавно, я написал, что тестовый код, написанный в первом посте, и передал его одного из наших клиентов , Я открыл запрос на обслуживание для JVM Oracle для этой проблемы. Номер Oracle SR: 3-11255842301 Oracle номер дефекта: 21694036 – Zman777

+0

Любое обходное решение для этого? – Manny

1

Несколько обновлений: эта проблема была исправлена ​​в ранней версии выпуска Java версии 9 (сборка 9-ea + 103-2016-01-27-183833.javare.4341.nc). Он по-прежнему существует в последней версии Java 8 (build 1.8.0_72-b15). По какой-то причине Oracle закрыла ошибку, которая была открыта из-за моего запроса на обслуживание против Java 6/7/8 по этой проблеме (как не воспроизводимая). Я пытаюсь заставить их снова открыть его.

Вот точно такая же проблема, возбужденное против OpenJDK, они установили его в OpenJDK 9: https://bugs.openjdk.java.net/browse/JDK-8062362

+1

Видимо, эта ошибка была исправлена ​​в Java 1.8.0_92: https://bugs.openjdk.java.net/browse/JDK-8141098 Я могу подтвердить, что это не происходит больше с Явой 1.8.0_102 – ChristophK

+0

спасибо всем вам за эту детективную работу, наконец, добившись прогресса в этом. – seinecle