Как вы форматируете огромный XML-файл в Java? - PullRequest
1 голос
/ 06 декабря 2011

Я должен обработать файл XML объемом 4 ГБ с использованием Java.

Проблема, с которой я столкнулся, заключается в том, что файл XML предоставляется в неформатированном виде, содержимое фактически находится на одной строке без разрывов строк.

Я хотел бы отформатировать XML-файл, чтобы он содержал разумные разрывы строк и отступы, чтобы в случае сбоя проверки (я использую JAXB для анализа), я мог легко найти и проверить проблемный раздел XML.

Кто-нибудь знает каркас, который может программно применять базовый формат XML в Java?

Ответы [ 6 ]

1 голос
/ 06 декабря 2011

CkXml предоставит вам то, что вам нужно, с помощью метода getXml.

CkXml xml = new CkXml();
xml.LoadXml("<root><company><name>Chilkat Software, Inc.</name><url>http://www.chilkatsoft.com/</url><phone>630-784-9670</phone></company></root>");
xml.getXml();

// Output looks like this:
// 
// <?xml version="1.0" encoding="utf-8" ?>
// 
// <root>
//     <company>
//         <name>Chilkat Software, Inc.</name>
//         <url>http://www.chilkatsoft.com/</url>
//         <phone>630-784-9670</phone>
//     </company>
// </root>

Существует также JTidy , который ориентирован на HTML, но должен работать достаточно хорошо для того, что вам нужно.

0 голосов
/ 06 декабря 2011

настройка синтаксического анализатора http://docs.oracle.com/javase/6/docs/api/javax/xml/parsers/SAXParser.html

создайте свой собственный обработчик содержимого и назначьте его синтаксическому анализатору саксофона:

saxParser.getXmlReader().setContentHandler(new MyContentHandler());

ContentHandler предоставляет доступ ко всем аспектам анализа иПозволяет вам обрабатывать XML по частям, если у него есть отдельные части, например:

<doc>
   <app></app>
   <app></app>
</doc>

вы можете разархивировать одно «приложение» за раз и обработать его перед тем, как попробовать следующее.

0 голосов
/ 06 декабря 2011

Вы можете использовать преобразование идентичности JAXP, что-то вроде этого:

javax.xml.transform.Source xmlSource = 
    new javax.xml.transform.stream.StreamSource(xmlFile);
javax.xml.transform.Result result = 
    new javax.xml.transform.stream.StreamResult(System.out);
javax.xml.transform.TransformerFactory transFact = 
    javax.xml.transform.TransformerFactory.newInstance();
javax.xml.transform.Transformer trans = 
    transFact.newTransformer();
trans.setOutputProperty("indent", "yes")
trans.transform(xmlSource, result);

Если повезет, это будет потоковое преобразование (оно обязательно будет, если TransformerFactory - Saxon).

Вы могли бы расширить этот подход, чтобы вставить потоковый шаг проверки в конвейер, избегая необходимости делать два прохода по данным. Если вы делаете все это в Саксонии, дополнительный бонус заключается в том, что отступы будут чувствительны к схеме - гарантируя, что отступы никогда не нарушат достоверность схемы.

Однако, хотя это соответствует заявленному требованию, я не уверен, что оно достигнет основных целей. Отступы сделаны, чтобы сделать данные удобочитаемыми. Рассматривали ли вы, какие инструменты вы будете использовать для отображения и редактирования вручную документа объемом 4 ГБ? Я не могу думать ни о ком, кто сделает работу, и удобство использования было бы ужасно. Кроме того, документ 4Gb, скорее всего, генерируется машиной, поэтому, если он недействителен, вам нужно исправить созданную им программу, а не сами данные - вполне вероятно, что любые ошибки в данных будут повторяться систематически много раз.

0 голосов
/ 06 декабря 2011

Я бы рассмотрел использование Transformer.Что-то вроде следующего:

Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
StreamResult tranformedDoc = new StreamResult(new StringWriter());
DOMSource source = new DOMSource(new Document()); // Insert content here.

transformer.transform(source, transformedDoc);

// Output string to byte array
return transformedDoc.getWriter().toString().getBytes();

Учитывая размер вашего XML, я не знаю, будет ли это хорошим решением для вас, но это отправная точка.Также, возможно, есть и более эффективные способы сделать это, поэтому они будут открыты для критики.

0 голосов
/ 06 декабря 2011

Я предполагаю, что XML правильно сформирован, но не действителен.Если вы сами генерируете XML через JAXB, вы можете выводить понятный человеку XML, когда вы упорядочиваете объекты.Ваш Marshaller необходим для предоставления возможности форматированного вывода.Вы устанавливаете свойство следующим образом:

marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

Если документ предоставлен вам (а вы его не генерируете), возможно, с таким инструментом, как UltraEdit , будет проще работать.Он обрабатывает большие документы и форматирует / редактирует XML.Существует бесплатная пробная версия, поэтому, если это краткосрочная проблема, возможно, вы сможете решить ее в течение пробного периода.

0 голосов
/ 06 декабря 2011

Не уверен, но как насчет JTidy ?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...