Как проверить кодировку файла xml
Покинул форум
Сообщений всего: 3
Дата рег-ции: Окт. 2009
Помог: 0 раз(а)
Есть файл xml вида:
Извиняюсь за бестолковость, но когда я начинаю читать файл — то мне сразу выводится вторая строчка. Как прочитать тип кодировки средствами php ?
Когда обрабатываю не зная кодировки — вылетает ошибка о неверном символе.
Использую стандартный парсер (xml_parser_create и т.д.)
Другие парсеры не подходят, т.к. формат файла не соответствует стандартам и не парсится.
(Отредактировано автором: 19 Октября, 2009 — 11:32:05)
Отправлено: 19 Октября, 2009 — 12:16:26
Здесь могла бы быть ваша реклама
Покинул форум
Сообщений всего: 4574
Дата рег-ции: Июль 2006
Откуда: Israel
Помог: 3 раз(а)
Покажи пожалуйста как именно ты читаешь файл.
Кроме того
Цитата:
Starting from PHP 5, the input encoding is automatically detected, so that the encoding parameter specifies only the output encoding
Отправлено: 19 Октября, 2009 — 12:47:47
Покинул форум
Сообщений всего: 3
Дата рег-ции: Окт. 2009
Помог: 0 раз(а)
читаю через xml_parser_create, вставляя рекурсивно куски файла полученные через fread (file, 4096) и проверяя «вручную» к какому блоку они принадлежат. Структура файла нестандартная
Для каждой кодировки я вынужден делать конверсию (кроме умолчальной UTF-8).
Причем если пытаюсь считать «неправильную» кодировку — то скрипт вылетает с ошибкой.
Вопрос то не про xml, а про то как прочитать заголовок файла. Нагуглить ничего толкового не могу.
Приведенная функция помочь не должна т.к. xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, ‘UTF-8’);
А мне нужно get 😉
(Отредактировано автором: 19 Октября, 2009 — 12:49:49)
Отправлено: 19 Октября, 2009 — 13:56:24
Здесь могла бы быть ваша реклама
Покинул форум
Сообщений всего: 4574
Дата рег-ции: Июль 2006
Откуда: Israel
Помог: 3 раз(а)
Если честно, я не очень понимаю в чем проблема.
Прочитать первую строку файла можно стандартным ифункциями чтения fread, file_get_contents , но зачем парсеру передавать xml по кускам, когда он может его сам читать из файла, сам распознавать его кодировку и сам все делать — я не понимаю.
На всякий случай, для наглядности, привидите пожалуйста свой код и пример того, что получается и что должно получиться.
Отправлено: 20 Октября, 2009 — 07:47:54
Покинул форум
Сообщений всего: 4555
Дата рег-ции: Февр. 2007
Откуда: Симферополь
Помог: 98 раз(а)
прочитайте кусок файла и регуляркой выдерните encoding.
——
Список фильмов с описанием, блекджеком и. для Joomla? -> https://киноархив[dot]com
Демо нового движка для сайта php.su -> php[dot]su, проект на гитхабе
Отправлено: 20 Октября, 2009 — 09:05:11
Покинул форум
Сообщений всего: 3
Дата рег-ции: Окт. 2009
Помог: 0 раз(а)
Народ, а вы точно пробовали читать файл xml через fread?
Я же написал, что он почему то читается со второй строчки.
Это мой локальный пеолтергейст (сам кстати удивился) или как то специфически его читать надо?
Отправлено: 20 Октября, 2009 — 10:30:59
Покинул форум
Сообщений всего: 4350
Дата рег-ции: Авг. 2008
Откуда: Москва
Помог: 57 раз(а)
Bazila пишет:
Народ, а вы точно пробовали читать файл xml через fread?
Для fread не важно, xml, txt, mp3. Не может он читаться со второй строчки. Просто ты, наверное считываешь ее где-то отдельно от всего основного и теряешь.
Отправлено: 20 Октября, 2009 — 13:30:26
Покинул форум
Сообщений всего: 4555
Дата рег-ции: Февр. 2007
Откуда: Симферополь
Помог: 98 раз(а)
Как прочитать xml файл в указанной в нём кодировке на javascript
Есть клиентское приложение (НЕ node.js!), которое обрабатывает xml файлы. Юзер подгружает их на страницу, и дальше их надо парсить в браузере. Очень упрощенно код такой:
function openFile(event) < let input = event.target; let reader = new FileReader(); reader.onload = function () < parse(reader.result); >; reader.onerror = function () < console.log(reader.error); >; reader.readAsText(input.files[0]); > function parse(text) < let parser = new DOMParser(); let xml = parser.parseFromString(text, "text/xml"); console.log(xml.xmlEncoding); //ок, но что дальше? for (let row of xml.getElementsByTagName("row")) < console.log(row.getAttribute("name"), row.firstChild.nodeValue); >>
Содержимое XML файла значения не имеет, для примера:
значение
Если файл в кодировке UTF-8 , то все хорошо. Но он может быть, например, в кодировке windows-1251 , тогда структура сохраняется, но внутри имя и значение будут знаками вопроса. Если я вызову чтение с явным указанием кодировки, то все будет работать:
reader.readAsText(input.files[0], 'windows-1251');
Но проблема в том, что я не знаю, какая она изначально. Как быть?
Как проверить кодировку файла xml
Профиль
Группа: Участник
Сообщений: 309
Регистрация: 25.1.2006
Репутация: нет
Всего: нет
Слышал, что SAX-парсер выбирает кодировку из заголовка xml-файла. Если такую не находит, то использует utf-8.
Вопрос мой задан с тем, чтобы подстраховаться.
Например такой вариант: мне присылают xml-файл. В заголовке написана кодировка Cp-1251, но на самом деле кодировка — utf-8. В данном случае парсер разберёт документ как Cp-1251. Это может быть чревато разбором русских символов.
Возможно у кого-то есть решение?
P.S. Смотрел класс InputSource. Там есть метод getEncoding. Но когда делаю так:
| Код |
| InputSource iSource = new InputSource(new FileInputStream(«c:/1.xml»)); System.out.println(iSource.getEncoding()); |
Вывод на консоль: null.
Вобщем кто может, помогите чем можете
Спасибо.
Leprechaun Software Developer
Профиль
Группа: Модератор
Сообщений: 15703
Регистрация: 24.3.2004
Репутация: 207
Всего: 535
В InputSource можно передать Reader, и тогда за кодировку уже будет отвечать Reader, на параметр пролога парсер обращать внимание не будет.
Вопрос только в том, как определить в какой кодировке файл? На мой взгляд это перекладывание проблемы с больной головы на здоровую. Если в прологе написано, что кодировка Cp-1251, то там и должна быть кодировка Cp-1251, а не какая нибудь другая. А если нет, то это невалидный XML, и это уже проблемы того кто его создавал.
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don’t take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don’t read it.
Профиль
Группа: Участник
Сообщений: 309
Регистрация: 25.1.2006
Репутация: нет
Всего: нет
| Цитата(LSD @ 29.3.2008, 19:58) |
| Вопрос только в том, как определить в какой кодировке файл? На мой взгляд это перекладывание проблемы с больной головы на здоровую. Если в прологе написано, что кодировка Cp-1251, то там и должна быть кодировка Cp-1251, а не какая нибудь другая. А если нет, то это невалидный XML, и это уже проблемы того кто его создавал. |
Согласен полностью насчёт того, что проблемы создающего. Но если это будет реально дурная голова. Например человек создал в блокноте xml-файл и написал в заголовке кодировку UTF-8. Как доказать, что кодировка Cp1251?
P.S. насчёт определения — скачал вот здесь http://www.apache.org/dist/xml/commons/ библиотеку resolver.jar.
Вот набросал небольшой примерчик (точнее спёр его полностью ). Если кому интересно, то вот:
| Код |
| import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.Vector; |
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.apache.log4j.Logger;
import org.apache.xml.resolver.CatalogManager;
import org.apache.xml.resolver.tools.CatalogResolver;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
import org.xml.sax.ext.Locator2;
import org.xml.sax.ext.Locator2Impl;
import org.xml.sax.helpers.DefaultHandler;
public class Props private static final String JAXP_SCHEMA_LANGUAGE = «http://java.sun.com/xml/jaxp/properties/schemaLanguage»;
private static final String W3C_XML_SCHEMA = «http://www.w3.org/2001/XMLSchema»;
private static final String JAXP_SCHEMA_SOURCE = «http://java.sun.com/xml/jaxp/properties/schemaSource»;
private static CatalogResolver xmlCatalogResolver;
private static final class CharsetHandler implements ContentHandler private Locator2Impl loc2impl;
private Locator2 fLocator;
public void setDocumentLocator(Locator locator) if (locator instanceof Locator2) fLocator = (Locator2) locator;
> else Logger.getLogger(this.getClass().getName()).error(
«There’s no getEncoding() method in »
+ locator.getClass().getName());
throw new RuntimeException(
«Используется старая версия xml-парсера, не поддерживающая SAX2 Extensions 1.1 (beta1)»);
>
public String getCharset() return loc2impl.getEncoding();
>
public String getVersion() return loc2impl.getXMLVersion();
>
// все остальные методы не используем
public void endDocument() throws SAXException >
public void startDocument() throws SAXException >
public void characters(char[] ch, int start, int length)
throws SAXException >
public void ignorableWhitespace(char[] ch, int start, int length)
throws SAXException >
public void endPrefixMapping(String prefix) throws SAXException >
public void skippedEntity(String name) throws SAXException >
public void processingInstruction(String target, String data)
throws SAXException >
public void startPrefixMapping(String prefix, String uri)
throws SAXException >
public void endElement(String namespaceURI, String localName,
String qName) throws SAXException >
public void startElement(String namespaceURI, String localName,
String qName, Attributes atts) throws SAXException
if (fLocator != null) loc2impl = new Locator2Impl(fLocator);
fLocator = null;
>
>
>
private static CharsetHandler contentHandler = new CharsetHandler();
public static void main(String args[]) throws ParserConfigurationException, SAXException, FileNotFoundException, IOException ThreadLocal xmlReader = new ThreadLocal();
final ThreadLocal validationLogWarnings = new ThreadLocal();
final ThreadLocal validationLogErrors = new ThreadLocal();
final ThreadLocal validationLogFatalErrors = new ThreadLocal();
final int stopValidationOnError = 5;
System.out.println(«begin. «);
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser;
factory.setValidating(true);
saxParser = factory.newSAXParser();
saxParser.setProperty(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA);
XMLReader reader = saxParser.getXMLReader();
reader.setFeature(«http://apache.org/xml/features/allow-java-encodings»,true);
CatalogManager catalogManager = new CatalogManager();
catalogManager.setCatalogFiles(«c:/CatalogManager.properties»);
// System.out.println(«class name=»+catalogManager.getCatalogClassName());
// catalogManager.setCatalogFiles(«c:/CatalogManager.properties»);
Vector v = catalogManager.getCatalogFiles();
System.out.println(catalogManager.getPrivateCatalog().getCurrentBase());
Enumeration enumer = v.elements();
xmlCatalogResolver = new CatalogResolver();
reader.setErrorHandler(new DefaultHandler() private int errorNumber = 0;
public void warning (SAXParseException e) throws SAXException ((List) validationLogWarnings.get()).add(e);
>
public void error(SAXParseException e) throws SAXException ((List) validationLogErrors.get()).add(e);
if (stopValidationOnError!=-1 && ++errorNumber>=stopValidationOnError)
throw e;
>
public void fatalError (SAXParseException e) throws SAXException ((List) validationLogFatalErrors.get()).add(e);
throw e;
>
>);
reader.setContentHandler(contentHandler);
xmlReader.set(reader);
validationLogWarnings.set(new ArrayList());
validationLogErrors.set(new ArrayList());
validationLogFatalErrors.set(new ArrayList());
((XMLReader) xmlReader.get()).parse(new InputSource(new FileInputStream(«c:/1.xml»)));
String docEncoding = contentHandler.getCharset();
System.out.println(«docEncoding = «+ docEncoding);
System.out.println(«Документ соответствует схеме»);
>
>
Для того, чтобы это всё заработало необходим файл CatalogManager.properties. Запихнуть его надо в папку с этим классом. Пробовал переопределять местоположение файла — не вышло. Может кто знает как это сделать?
CatalogManager.properties:
| Код |
| #relative-catalogs=false xml.catalog.verbosity=99 catalogs=xsd/catalog.xml |
папка xsd должна также быть в одной директории с классом.
в папке xsd должен быть файл catalog.xml и схема.
catalog.xml:
Проверка XML‑файла
Мы не можем распознать и проверить этот файл. К нерегламентируемым форматам относятся протокол согласования цен, реестр сертификатов и документы в произвольном формате.
Неверный формат файла. Загрузите файл в формате XML
Неверная кодировка файла. Загрузите файл с кодировкой windows-1251
Невозможно определить тип файла. Добавьте в файл атрибут КНД
Найти КНД можно в нашем справочнике документов. КНД указан в приказе ФНС к документу и в примере XML документа, который можно скачать.
Ошибка на странице
Попробуйте обновить страницу позже. Если ошибка повторяется —
напишите нам об этом в чат поддержки .

Если вам нужна помощь при написании XML-файлов, подключайтесь к Диадоку и мы проведем интеграцию с вашей учетной системой.