Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как сохранить русский текст в dom4j, Странности с UTF-8 
:(
    Опции темы
_Y_
Дата 2.12.2012, 12:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1651
Регистрация: 27.11.2006

Репутация: 5
Всего: 34



Что-то не получается у меня сохранить русский декст в dom4j XML документе. Пока документ формируется програмно, все в порядке, а при сохранении записывается ANSI файл вместо UML и русские буквы, естественно, сохраняются как вопросы.

Документ сохраняю вот так:
Код

    public void save(File file){

     try {
         XMLWriter writer = new XMLWriter(new FileWriter(file));
         writer.write(document);
         writer.close();
     } catch (IOException e) {
         e.printStackTrace();
         System.exit(0);
     }         
    }


Сохраняется вот такой документ

Код

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <DocumentDescription/>
  <ReusableNodes/>
  <TreePart>
    <PNode id="89" title="?????????" time="2012-12-02">?????</PNode>
  </TreePart>
</root>


Может быть надо где-то какие-то флаги ставить, о которых я напрочь забыл?
Спасибо!

ЗЫ: Кстати, еще одна заморочка. Почему-то вот этот валидатор ругается на элемент <root>.  Другие валидаторы претензий не имеют. Но это, наверное, мелочь.



Это сообщение отредактировал(а) _Y_ - 9.12.2012, 11:53


--------------------
Я вот в этом поучаствовал: http://sbor-nik.appspot.com/kick.jsp?id=sbor5737960678883328 (на правах саморекламы:)
PM MAIL WWW   Вверх
zergi
Дата 2.12.2012, 18:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 31.10.2012

Репутация: нет
Всего: нет



Вот тут пример, должен работать: 

http://cmhbl0g.blogspot.com/2011/12/writin...-documents.html
PM MAIL   Вверх
_Y_
Дата 2.12.2012, 23:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1651
Регистрация: 27.11.2006

Репутация: 5
Всего: 34



zergi, спасибо, вроде работает.

Это сообщение отредактировал(а) _Y_ - 3.12.2012, 11:43


--------------------
Я вот в этом поучаствовал: http://sbor-nik.appspot.com/kick.jsp?id=sbor5737960678883328 (на правах саморекламы:)
PM MAIL WWW   Вверх
_Y_
Дата 3.12.2012, 11:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1651
Регистрация: 27.11.2006

Репутация: 5
Всего: 34



А вот и нет. Рано обрадовался. Русский текс сохраняет, зато навая ошибка полезла. Сохраняю вот  такой XML документ (даже и без всякой кириллицы):
Код

<?xml version="1.0" encoding="UTF-8"?>
<root>
     <DocumentDescription/>
     <ReusableNodes/>
     <TreePart>
          <PNode title="Level1" time="2012-12-03" id="8q">
               <PNode title="Level2" time="2012-12-03" id="8r"/>
          </PNode>
     </TreePart>
</root>

Если испльзую формат по дефолту:
Код

XMLWriter writer = new XMLWriter(new OutputStreamWriter(new FileOutputStream(file)));
writer.write(document);
writer.close();

Документ сохраняется без проблем. Если же, пользуюсь рекомендованным выше форматом:
Код

OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("UTF-8");
XMLWriter writer = new XMLWriter(new OutputStreamWriter(
         new FileOutputStream(file), "UTF8"),
         format);
writer.write(document);
writer.close();

Выдает ошибку:
Код

Exception in thread "AWT-EventQueue-0" java.lang.StringIndexOutOfBoundsException: String index out of range: -1
    at java.lang.String.charAt(Unknown Source)
    at org.dom4j.io.XMLWriter.writeElementContent(XMLWriter.java:1074)
    at org.dom4j.io.XMLWriter.writeElement(XMLWriter.java:954)
    at org.dom4j.io.XMLWriter.writeNode(XMLWriter.java:1301)
    at org.dom4j.io.XMLWriter.writeElementContent(XMLWriter.java:1086)
    at org.dom4j.io.XMLWriter.writeElement(XMLWriter.java:954)
    at org.dom4j.io.XMLWriter.writeNode(XMLWriter.java:1301)
    at org.dom4j.io.XMLWriter.writeElementContent(XMLWriter.java:1086)
    at org.dom4j.io.XMLWriter.writeElement(XMLWriter.java:954)
    at org.dom4j.io.XMLWriter.writeNode(XMLWriter.java:1301)
    at org.dom4j.io.XMLWriter.write(XMLWriter.java:344)
        ..........................

Начинаю копаться в коде org.dom4j.io.XMLWriter - вроде бы находит в документе Node типа Text со строкой нулевой длины, что ему и не нравится, т.к. делает он вот такую операцию:
Код

lastTextChar = txt.charAt(txt.length() - 1);

После нескольких эксериментов заподозрил (но не уверен), что недовольство вызывает XML элемент <PNode title="Level1".... Но почему? И почему проблема только если выбирается именно UNICOD?

Подскажите, пожалуйста.





--------------------
Я вот в этом поучаствовал: http://sbor-nik.appspot.com/kick.jsp?id=sbor5737960678883328 (на правах саморекламы:)
PM MAIL WWW   Вверх
zergi
Дата 3.12.2012, 14:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 31.10.2012

Репутация: нет
Всего: нет



У меня приведенный XML отлично сохранился.
Как вы формируете сам документ в коде?
PM MAIL   Вверх
_Y_
Дата 3.12.2012, 22:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1651
Регистрация: 27.11.2006

Репутация: 5
Всего: 34



zergi, проект не маленький. Попробую ободрать его копию оставив только создание и сохранение документа. Может проблема и локализуется. А нет - будет код, пригодный к обсуждению. Но на это мне надо несколько дней.


--------------------
Я вот в этом поучаствовал: http://sbor-nik.appspot.com/kick.jsp?id=sbor5737960678883328 (на правах саморекламы:)
PM MAIL WWW   Вверх
_Y_
Дата 5.12.2012, 00:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1651
Регистрация: 27.11.2006

Репутация: 5
Всего: 34



Оператор, вызывающий ошибку, я нашел. А вот почему она возникает - малопонятно. Вот полный код теста:
Код

package zbush;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.Iterator;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.QName;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import org.dom4j.tree.FlyweightAttribute;

public class Test1 {

    public static void main(String[] args) {
        
        System.out.println("----------- Create document -------------");

        Document doc = DocumentHelper.createDocument();
     Element root = doc.addElement( "root" );

     root.clearContent();
     root.addElement("DocumentDescription");
     root.addElement("ReusableNodes");
     root.addElement("TreePart");
     
        System.out.println("----------- Create Level1 -------------");
     
     Iterator i = root.elementIterator("TreePart");
     
     Element treePartElement = (Element)i.next();
     
     Element level1 = treePartElement.addElement("PNode");
     level1.add(new FlyweightAttribute(new QName("id"), "8q"));
        //level1.setText("");
        level1.add(new FlyweightAttribute(new QName("title"), "Level1"));
        level1.add(new FlyweightAttribute(new QName("time"), "2012-12-03"));

     System.out.println("----------- Save Default ANSI -------------");

     try {
         XMLWriter writer = new XMLWriter(new OutputStreamWriter(
                 new FileOutputStream(new File("c:/temp/ANSI_1.xml"))));
         writer.write(doc);
         writer.close();
     } catch (IOException e) {
         e.printStackTrace();
     }
     
     System.out.println("----------- Save UTF-8 -------------");

       try {
         OutputFormat format = OutputFormat.createPrettyPrint();
         format.setEncoding("UTF-8");
         XMLWriter writer = new XMLWriter(new OutputStreamWriter(
                 new FileOutputStream(new File("c:/temp/UTF8_1.xml")), "UTF8"),
                 format);
         writer.write(doc);
         writer.close();
     } catch (IOException e) {
         e.printStackTrace();
      }
     
        System.out.println("----------- Create Level2 -------------");
          
     Element level2 = level1.addElement("PNode");
     level2.add(new FlyweightAttribute(new QName("id"), "8r"));
        level2.setText("");
     level2.add(new FlyweightAttribute(new QName("title"), "Level2"));
        level2.add(new FlyweightAttribute(new QName("time"), "2012-12-03"));    

     System.out.println("----------- Save Default ANSI -------------");

     try {
         XMLWriter writer = new XMLWriter(new OutputStreamWriter(
                 new FileOutputStream(new File("c:/temp/ANSI_2.xml"))));
         writer.write(doc);
         writer.close();
     } catch (IOException e) {
         e.printStackTrace();
     }
     
     System.out.println("----------- Save UTF-8 -------------");

       try {
         OutputFormat format = OutputFormat.createPrettyPrint();
         format.setEncoding("UTF-8");
         XMLWriter writer = new XMLWriter(new OutputStreamWriter(
                 new FileOutputStream(new File("c:/temp/UTF8_2.xml")), "UTF8"),
                 format);
         writer.write(doc);
         writer.close();
     } catch (IOException e) {
         e.printStackTrace();
      } 


        System.out.println("----------- END -------------");

    }
}

Ошибка возникает если разкомментировать оператор level1.setText(""); (строка 39).
При этом если его раскоментировать, но вместо пустой строки вставить любую непустую, ошибки не будет. Странно как-то. Я всегда считал, что пустая строка так же легитимна, как и любая другая, в том числе и в UTF-8. Кстати, при отсутствии вложенных элементов, ошибка не возникает и с пустой строкой   - оператор level2.setText(""); (строка 72) ошибки не дает.

С удовольствием услышу мнение по причинам таких странных заморочек.


Это сообщение отредактировал(а) _Y_ - 9.12.2012, 11:31


--------------------
Я вот в этом поучаствовал: http://sbor-nik.appspot.com/kick.jsp?id=sbor5737960678883328 (на правах саморекламы:)
PM MAIL WWW   Вверх
_Y_
Дата 9.12.2012, 11:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1651
Регистрация: 27.11.2006

Репутация: 5
Всего: 34



Я продолжил эксперименты, сильно упростил пример и надеюсь, что кто-то знает объяснение происходящих странностей. Пытаюсь сохранить вот такой документ в UTF-8 с помощью dom4j:
Код

<?xml version="1.0" encoding="UTF-8"?>
<root>
     <TreePart>
          <PNode1>
               <PNode2></PNode2>
          </PNode1>
     </TreePart>
</root>

Использую вот такой код (тот же пример, что и раньше, но сильно упрощенный):
Код

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.Iterator;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;

public class Test1 {

   public static void main(String[] args) {
        
    String textUnderInvestigation = "";
        
     // Create document

    Document doc = DocumentHelper.createDocument();
     Element root = doc.addElement( "root" );

     root.clearContent();
      root.addElement("TreePart");
     
     // Create Level1 
   
     Iterator i = root.elementIterator("TreePart");
     
     Element treePartElement = (Element)i.next();
     
     Element level1 = treePartElement.addElement("PNode1");
       level1.setText(textUnderInvestigation);
     
    // Create Level2
          
     Element level2 = level1.addElement("PNode2");
      level2.setText("");
        
     System.out.println("----------- Save Default ANSI -------------");

     try {
         XMLWriter writer = new XMLWriter(new OutputStreamWriter(
                 new FileOutputStream(new File("c:/temp/ANSI_2.xml"))));
         writer.write(doc);
         writer.close();
     } catch (IOException e) {
         e.printStackTrace();
     }
     
     System.out.println("----------- Save UTF-8 -------------");

       try {
         OutputFormat format = OutputFormat.createPrettyPrint();
         format.setEncoding("UTF-8");
         XMLWriter writer = new XMLWriter(new OutputStreamWriter(
                 new FileOutputStream(new File("c:/temp/UTF8_2.xml")), "UTF8"),
                 format);
         writer.write(doc);
         writer.close();
     } catch (IOException e) {
         e.printStackTrace();
      } 
     
        System.out.println("----------- END -------------");
    }
}

Т.е. документ сохраняется в два раза: как ANSI и как UTF-8. Но сохранение в  UTF-8 выдат ошибку. Ошибка пропадает, если переменной textUnderInvestigation присвоить любое не-пустое значение. Теперь самое интересное. Ошибка пропадает даже если присвоить значение "\n", но при этом документ все равно записывается без переносов строки.

Ну очень хочется, чтобы кто-нибудь объяснил мне. Почему возникают все эти странные заморочки? Я бы списал все на особенности dom4j, но почему такое происходит ТОЛЬКО при сохранении в UTF-8?





--------------------
Я вот в этом поучаствовал: http://sbor-nik.appspot.com/kick.jsp?id=sbor5737960678883328 (на правах саморекламы:)
PM MAIL WWW   Вверх
Pawl
Дата 9.12.2012, 13:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 649
Регистрация: 22.4.2008
Где: Витебск

Репутация: 7
Всего: 28



Объяснения этому я пока не знаю, НО, когда я в строке 55 код
Код

OutputFormat format = OutputFormat.createPrettyPrint();

заменил на
Код

OutputFormat format = new OutputFormat();

у меня все заработало прекрасно, и если textUnderInvestigation оставлять пустым и если туда что-то написать. Надо будет почитать docs по методу createPrettyPrint ну и по классу OutputFormat заодно.
Возможно, разгадка кроется в описании конструктора OutputFormat():
Цитата

Creates an OutputFormat with no additional whitespace (indent or new lines) added

А метод    createPrettyPrint() - это
Цитата

A static helper method to create the default pretty printing format.
 И фиг знает, что там под pretty printing format имеется в виду! Да, и еще. Ваш файл ANSI_2.xml все-равно имеет кодировку UTF-8:
Код

<?xml version="1.0" encoding="UTF-8" ?>

Если надо, чтобы было, к примеру, 
Код

<?xml version="1.0" encoding="ISO-8859-1" ?>
, надо сделать так

Это сообщение отредактировал(а) Pawl - 9.12.2012, 13:45


--------------------
В действительности всё совсем не так, как на самом деле
PM MAIL   Вверх
_Y_
Дата 9.12.2012, 21:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1651
Регистрация: 27.11.2006

Репутация: 5
Всего: 34



Спасибо. Подумаю над этим.

Цитата(Pawl @  9.12.2012,  13:16 Найти цитируемый пост)
Да, и еще. Ваш файл ANSI_2.xml все-равно имеет кодировку UTF-8:
<?xml version="1.0" encoding="UTF-8" ?>

В том и шекспир, что в XML заголовке выводится UTF-8, но файл-то пишется в  ANSI. В UTF-8 он пишется только вторым вариантом.



--------------------
Я вот в этом поучаствовал: http://sbor-nik.appspot.com/kick.jsp?id=sbor5737960678883328 (на правах саморекламы:)
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0766 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.