Имя: Пароль:
1C
 
XML - проблемы с кодировкой
0 RomaH
 
naïve
31.01.15
15:07
через XDTO  создаю текст XML
потом пишу его в файл и проверяю на соответствие схеме

        ЗаписьXML = Новый ЗаписьXML;
        
        ЗаписьXML.УстановитьСтроку();
        ЗаписьXML.ЗаписатьОбъявлениеXML();
        ФабрикаXDTO.ЗаписатьXML(ЗаписьXML, КорневойРаздел);
        
        Возврат ЗаписьXML.Закрыть();

это возвращает получившийся текст ХМЛ в реквизит документа типа Строка(0)

потом:


    ВыводитьВсеОшибки = Истина;
    
    ИмяФайла = ПолучитьИмяВременногоФайла("xml");
    ИмяФайлаСхемы = ПолучитьИмяВременногоФайла("xsd");
    
    ФайлРеестра = Новый ТекстовыйДокумент;
    ФайлРеестра.УстановитьТекст(Объект.ТекстВыгрузки);
    ФайлРеестра.Записать(ИмяФайла,"windows-1251");
    
    ФайлСхемы = Новый ТекстовыйДокумент;
    ФайлСхемы.УстановитьТекст(Объект.ТекстСхемыДокумента);
    ФайлСхемы.Записать(ИмяФайлаСхемы,"windows-1251");
    
    Попытка
        Схема=Новый COMОбъект("MSXML2.XMLSchemaCache.6.0");
    Исключение
        Сообщить("Не удалось создать объект XMLSchemaCache (возможно, не установлен MSXML 6)");
        Возврат;
    КонецПопытки;
    
    Попытка
        Схема.add("",ИмяФайлаСхемы);
    Исключение
        Сообщить("Не удалось подключить схему: "+ИмяФайлаСхемы);
        Схема=Неопределено;
        Возврат;
    КонецПопытки;
    
    Попытка
        ДОМ=Новый COMОбъект("MSXML2.DOMDocument.6.0");
    Исключение
        Сообщить("Не удалось создать объект DOMDocument (возможно, не установлен MSXML 6)");
        Схема=Неопределено;
        Возврат;
    КонецПопытки;
    
    ДОМ.schemas=Схема;
    ДОМ.async=Ложь;
    ДОМ.validateOnParse=Истина;
    ДОМ.resolveExternals=Истина;
    Если ВыводитьВсеОшибки Тогда
        ДОМ.SetProperty("MultipleErrorMessages",Истина);
    КонецЕсли;
    ДОМ.load(ИмяФайла);
    
    Если (ДОМ.parseError.errorCode<>0) Тогда
        // ошибки при проверке правильности
        Сообщить("При проверке по схеме выявлены ошибки!");
        Если ВыводитьВсеОшибки Тогда
            Для каждого parseError из ДОМ.parseError.AllErrors  Цикл
                Сообщить(parseError.reason);
                Сообщить(parseError.srcText);
            КонецЦикла;
        Иначе
            Сообщить(ДОМ.parseError);
        КонецЕсли;
    Иначе
        Сообщить("Файл успешно прошёл проверку по схеме!");
        РезПроверки=Истина;
    КонецЕсли;


получаю ошибку на первом же атрибуте где встречается кириллица:
В текстовом комментарии обнаружен недопустимый знак.

                <patient patientcod="44240" surname="


заголовок схемы:

<?xml version="1.0" encoding="Windows-1251"?>
<!-- edited with XMLSpy v2011 rel. 2 (http://www.altova.com) by TeaM DJiNN (TeaM DJiNN) -->
<!--W3C Schema generated by XMLSpy v2009 sp1 (http://www.altova.com)-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">;
    <xs:element name="package">
1 Zhuravlik
 
31.01.15
16:08
мб нужно пересохранить в другой кодировке?
2 tridog
 
31.01.15
16:29
(0) Писать через XDTO, но читать через "MSXML2.DOMDocument.6.0" - это такой особый вид сексуального извращения?
3 RomaH
 
naïve
31.01.15
21:52
(2) ну на всякий случай
и в общем-то он себя оправдал - файлик-то не проходит проверку

(1) в смысле? - в какой другой? и как это "пересохранить?
4 RomaH
 
naïve
31.01.15
21:54
(2) прикол в том, что XDTO выдает ошибку, например на запись текста в число, но в общем-то пишет  просто атрибут отсутсвует
но в схеме этот атрибут обязателен

на выходе имею XML без обязательного атрибута, однако
5 Jaap Vduul
 
31.01.15
23:21
(3) >> в смысле? - в какой другой?
ЗаписьXML.УстановитьСтроку("windows-1251");
6 Zhuravlik
 
01.02.15
00:09
(5) скорее ЗаписьXML.УстановитьСтроку("utf<смотреть в сп>");
7 RomaH
 
naïve
01.02.15
19:46
(5)
    ФайлРеестра = Новый ТекстовыйДокумент;
    ФайлРеестра.УстановитьТекст(Объект.ТекстВыгрузки);
    ФайлРеестра.Записать(ИмяФайла,"windows-1251");

а это не подходит?
8 RomaH
 
naïve
02.02.15
07:35
блин, делаю:     

Запись = Новый ЗаписьXML;
Запись.ОткрытьФайл(ИмяФайла, "UTF-8");
Запись.ЗаписатьБезОбработки(Объект.ТекстВыгрузки);
Запись.Закрыть();


но мне надо "windows-1251"

"Требование на оплату / ответ на требование представляет собой один XML-файл с именем bill.xml в кодировке Windows-1251 (стандартная русская кодировка), упакованный архиватором 7-zip в архивный файл с именем"

другой вариант:
создаю XML файл в Notepad ++ устанавливаю ему кодировку windows-1251

копирую в него текст получивщшийся в 1С
сохраняю - проверяю - все ок

как в 1С создать сразу файл с нужной кодировкой. что бы валидацию проходил?
9 RomaH
 
naïve
02.02.15
07:45
+(8)
делаю:    

Запись = Новый ЗаписьXML;
Запись.ОткрытьФайл(ИмяФайла, "UTF-8");
Запись.ЗаписатьБезОбработки(Объект.ТекстВыгрузки);
Запись.Закрыть();

- проверка проходит
10 Рэйв
 
02.02.15
07:55
//----------Сериализация

Функция XML(Данные)
    ЗаписьXML = Новый ЗаписьXML();
    ЗаписьXML.УстановитьСтроку();
    СериализаторXDTO.ЗаписатьXML(ЗаписьXML, Данные);
    Возврат ЗаписьXML.Закрыть();
КонецФункции
//------Десериализация

Функция ДанныеИзXML(Стр)
    ЧтениеXML = Новый ЧтениеXML();
    ЧтениеXML.УстановитьСтроку(Стр);
    Возврат СериализаторXDTO.ПрочитатьXML(ЧтениеXML);
КонецФункции
11 RomaH
 
naïve
02.02.15
08:30
(10) и что мне в "данные" передать? готовый XML текст?
12 RomaH
 
naïve
02.02.15
08:30
(10) и чем мне это поможет с кодировкой?
13 ShoGUN
 
02.02.15
08:37
(12) После вот этого:
ФайлРеестра.Записать(ИмяФайла,"windows-1251");

Файл в какой кодировке сохраняется? Просто из всего понаписанного не понял, в чём проблема - 1С неправильно сохраняет, или парсер MS пытается неверно читать.
14 RomaH
 
naïve
02.02.15
08:38
еще раз:
имею текст XML сохраненный в реквизите документа типа строка(0)

задача - проверить его на валидность посхеме сохраненной в другом реквизите этого документа

делаю:

    ИмяФайла = ПолучитьИмяВременногоФайла("xml");
    ИмяФайлаСхемы = ПолучитьИмяВременногоФайла("xsd");
    
    ФайлРеестра = Новый ТекстовыйДокумент;
    ФайлРеестра.УстановитьТекст(Объект.ТекстВыгрузки);
    ФайлРеестра.Записать(ИмяФайла,"windows-1251");
    
    ФайлСхемы = Новый ТекстовыйДокумент;
    ФайлСхемы.УстановитьТекст(Объект.ТекстСхемыДокумента);
    ФайлСхемы.Записать(ИмяФайлаСхемы,"windows-1251");
    
    Попытка
        Схема=Новый COMОбъект("MSXML2.XMLSchemaCache.6.0");
    Исключение
        Сообщить("Не удалось создать объект XMLSchemaCache (возможно, не установлен MSXML 6)");
        Возврат;
    КонецПопытки;
    
    Попытка
        Схема.add("",ИмяФайлаСхемы);
    Исключение
        Сообщить("Не удалось подключить схему: "+ИмяФайлаСхемы);
        Схема=Неопределено;
        Возврат;
    КонецПопытки;
    
    Попытка
        ДОМ=Новый COMОбъект("MSXML2.DOMDocument.6.0");
    Исключение
        Сообщить("Не удалось создать объект DOMDocument (возможно, не установлен MSXML 6)");
        Схема=Неопределено;
        Возврат;
    КонецПопытки;
    
    ДОМ.schemas=Схема;
    ДОМ.async=Ложь;
    ДОМ.validateOnParse=Истина;
    ДОМ.resolveExternals=Истина;
    Если ВыводитьВсеОшибки Тогда
        ДОМ.SetProperty("MultipleErrorMessages",Истина);
    КонецЕсли;
    ДОМ.load(ИмяФайла);
    
    Если (ДОМ.parseError.errorCode<>0) Тогда
        // ошибки при проверке правильности

        Сообщить("При проверке по схеме выявлены ошибки!");
        Если ВыводитьВсеОшибки Тогда
            Для каждого parseError из ДОМ.parseError.AllErrors  Цикл
                Сообщить(parseError.reason);
                Сообщить(parseError.srcText);
            КонецЦикла;
        Иначе
            Сообщить(ДОМ.parseError);
        КонецЕсли;
    Иначе
        Сообщить("Файл успешно прошёл проверку по схеме!");
        РезПроверки=Истина;
    КонецЕсли;

получаю в итоге:


В текстовом комментарии обнаружен недопустимый знак.

                <patient patientcod="44240" surname="


хотя если открываю проверяемый файл блокнотом - то кирилица нормально читается
15 ShoGUN
 
02.02.15
08:42
(14) Блокнот автоматически определяет кодировку, и читает и то, и то.
Проблема у тебя, вероятно, в том, что в заголовке файла указана одна кодировка, а сам файл записан в другой. Вот я и пытаюсь понять, что и в какой именно.
Ты можешь не просто открыть блокнотом, а посмотреть, какую он при этом кодировку определяет?
16 RomaH
 
naïve
02.02.15
08:43
(13) вопрос - а как посмотреть в какой он кодировке?
17 mehfk
 
02.02.15
08:44
А в заголовке xml файла какая кодировка указана?
18 ShoGUN
 
02.02.15
08:46
(16) При "Сохранить как..." что пишет вот тут:
https://yadi.sk/i/INAUlU5oeQ6Zi
19 RomaH
 
naïve
02.02.15
08:46
Lister при открытии тоже ругается на кодировку
20 RomaH
 
naïve
02.02.15
08:47
(17) - никакой
<?xml version="1.0"?>
<package xmlns="http://tfoms.yar.ru/BILL/605"; xmlns:xs="http://www.w3.org/2001/XMLSchema"; xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">;
21 mehfk
 
02.02.15
08:48
если никакой - это значит что по-умолчанию принят UTF-8
22 RomaH
 
naïve
02.02.15
08:48
(18) ANSI
23 ShoGUN
 
02.02.15
08:49
(20) Если никакая не указана, то парсер по умолчанию использует то ли UTF-8, то ли UTF-16. Вот и твоя ошибка - укажи кодировку в заголовке.
24 RomaH
 
naïve
02.02.15
08:49
(21) где принят? достаточно заголовок добавить? какой?
25 ShoGUN
 
02.02.15
08:49
(24) <?xml version="1.0" encoding="Windows-1251"?>
26 mehfk
 
02.02.15
08:50
(24) Принят стандартом.
http://www.w3.org/TR/xml11/#sec-guessing
27 ShoGUN
 
02.02.15
08:52
(26) Там всё несколько сложнее :) Но если дополнительной информации нет, и никакое определение не проканало - то UTF-8.
28 RomaH
 
naïve
02.02.15
08:53
спасибо
29 mehfk
 
02.02.15
08:54
(27) Мне не надо объяснять.
Здесь можно обсудить любую тему при этом оставаясь на форуме для 1Сников, который нужен для работы. Ymryn