Имя: Пароль:
1C
1С v8
Как в XSD-схеме задать массив из одного элемента?
0 D_Pavel
 
23.09.15
06:58
Продукция в схеме так обозначена:

<xs:complexType name="Поставщик">
    <xs:element name="Продукция" type="tns:Продукция" maxOccurs="unbounded" />
</xs:complexType>

Если в XML много строк с Продукцией, то когда разбираю XML с помощью Фабрики, то все ок, в 1С Поставщик.Продукция - это массив:
          <Поставщик>
            <Продукция ПN="1"/>
            <Продукция ПN="2"/>
            <Продукция ПN="3"/>
          </Поставщик>
Если строка одна, то 1С считает это не массивом, а объектом: (Поставщик.Продукция - это объект)
          <Поставщик>
            <Продукция ПN="1"/>
          </Поставщик>

Как сделать чтобы 1С всегда считала Продукцию массивом, даже если ее всего один элемент? Может в схеме как-то по другому задать?
1 spock
 
23.09.15
07:08
Так?
<xs:complexType name="Поставщик">
    <xs:sequence>
        <xs:element name="Продукция" type="tns:Продукция" maxOccurs="unbounded" />
    </xs:sequence>
</xs:complexType>
2 D_Pavel
 
23.09.15
07:10
(1) нет, не так. Это то же самое что и у меня. Все равно как объект воспринимает :(
3 D_Pavel
 
23.09.15
08:44
Ап
4 D_Pavel
 
23.09.15
09:08
Как же долго просыпаются умные одноэсники на западе... А от восточных совсем никакой пользы.
5 Fragster
 
гуру
23.09.15
09:17
(0) а смысл сего действия?
6 D_Pavel
 
23.09.15
09:20
(5) Чтобы не получить исключение при обходе массива циклом, и не добавлять проверок на тип.
7 Serginio1
 
23.09.15
10:33
Поставь minOccurs="0"
8 Fragster
 
гуру
23.09.15
10:36
(7) это не сделает его массивом
9 Fragster
 
гуру
23.09.15
10:38
проблема в том, что в (0) неправильно читается. прошу привести пример кода и первой строки XML
10 Fragster
 
гуру
23.09.15
10:39
а также нужно учитывать то, что 1с не умеет работать с "неопределенным" пространством имен, т.е. и в XML и в схеме оно должно быть.
11 RomaH
 
naïve
23.09.15
10:40
ДанныеСчета = Неопределено;
    ИндексСчета = 0;
    
    Пока ПолучитьУзелСписка(ДанныеПациента.register_accounts.personal_account,ИндексСчета,ДанныеСчета) Цикл
        
Функция ПолучитьУзелСписка(СписокXDTO,Индекс,ЭлементСписка)
    
    Если ТипЗнч(СписокXDTO) = Тип("ОбъектXDTO") И Индекс = 0 Тогда
        ЭлементСписка = СписокXDTO;
        Индекс = Индекс + 1;
        Возврат Истина;    
    КонецЕсли;
    
    Если ТипЗнч(СписокXDTO) = Тип("СписокXDTO") И Индекс < СписокXDTO.Количество() Тогда
        ЭлементСписка = СписокXDTO.Получить(Индекс);
        Индекс = Индекс + 1;
        Возврат Истина;
    КонецЕсли;
    Индекс = Индекс + 1;
    
    Возврат Ложь;
    
КонецФункции
12 Fragster
 
гуру
23.09.15
11:09
(11) Интересует фрагмент ФабрикаXDTO.ПрочитатьXML(), как получается параметр "тип". Ну и фрагмент XML, где определяется пространство имен (чаще всего - корневой тег)
13 D_Pavel
 
23.09.15
11:14
(9) У меня правильно читается. Что именно не читается?
Как пример кода может повлиять на то что человек знающий ответ на мой вопрос зайдет в эту тему?
14 Fragster
 
гуру
23.09.15
11:15
(13) я знаю ответ на твой вопрос. у тебя XML читается не как объект твоего типа из схемы, а как anytype.
15 D_Pavel
 
23.09.15
11:16
(10) Пространство имен конечно же есть, иначе бы ошибка возникла еще на чтении XML.
16 D_Pavel
 
23.09.15
11:17
(14) Понял тебя. Сейчас проверю.
17 Serginio1
 
23.09.15
11:27
(8) Делает прекрасно

Такой массив будет прекрасно считываться и с одним элементом
minOccurs="0"
maxOccurs="unbounded"/>

А вот такой
minOccurs="1"
maxOccurs="unbounded"/>

При одном элементе будет давать элемент, а не список
18 D_Pavel
 
23.09.15
11:28
(17) Спасибо, КО! Темку можно закрыть.
19 Fragster
 
гуру
23.09.15
11:41
(17) нифига.
(18) нифига.
20 Fragster
 
гуру
23.09.15
11:41
вот правильное чтение:

Схема =
"<?xml version=""1.0"" encoding=""utf-8""?>
|<xs:schema xmlns=""test"" targetNamespace=""test"" xmlns:xs=""http://www.w3.org/2001/XMLSchema"&quot;
|  elementFormDefault=""qualified"" attributeFormDefault=""unqualified"">
|  <xs:element name=""test"" type=""test""/>
|  <xs:complexType name=""test"">
|    <xs:sequence>
|      <xs:element minOccurs=""1"" maxOccurs=""unbounded"" name=""ttt"" type=""xs:string""/>
|    </xs:sequence>
|  </xs:complexType>
|</xs:schema>";

ИмяФайлаСхемы = ПолучитьИмяВременногоФайла("xsd");
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.УстановитьТекст(Схема);
ТекстовыйДокумент.Записать(ИмяФайлаСхемы);

Фабрика = СоздатьФабрикуXDTO(ИмяФайлаСхемы);
УдалитьФайлы(ИмяФайлаСхемы);

XML =
"<?xml version = ""1.0"" encoding = ""utf-8""?>
|<test xmlns=""test""
|   xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"&quot;
|   xsi:schemaLocation=""test file:///X:/tmp/Untitled.xsd"">
|  <ttt>Привет!</ttt>
|</test>";
Чтение = Новый ЧтениеXML;
Чтение.УстановитьСтроку(XML);
Тип = Фабрика.Тип("test","test");
Объект = Фабрика.ПрочитатьXML(Чтение, Тип);
ТипТТТ = ТипЗнч(Объект.ttt);
21 Fragster
 
гуру
23.09.15
11:43
(20) хоть minOccurs="1", хоть 0, все равно будет список при maxOccurs="unbounded"
22 Fragster
 
гуру
23.09.15
11:44
а вот при отсутствии указания maxOccurs указание minOccurs в 0 делает тег необязательным. А свойство у результирующего объекта все равно будет.
23 Serginio1
 
23.09.15
11:47
(19) Ну да. Проверь. Я уже на эти грабли наступал.
Заодно посмотри чему равен  minOccurs по умолчанию
24 Fragster
 
гуру
23.09.15
11:48
(23) ты код запустил?
25 D_Pavel
 
23.09.15
11:50
(20) Зачем указываешь в XML это
xsi:schemaLocation=""test file:///X:/tmp/Untitled.xsd""
если у тебя в прочтении XML фабрикой и так указан тип?

Тип = Фабрика.Тип("test","test");
Объект = Фабрика.ПрочитатьXML(Чтение, Тип);
26 Fragster
 
гуру
23.09.15
11:55
(25) это потому что XML делался во внешнем редакторе. можно удалить, поведение кода не изменится.
27 D_Pavel
 
23.09.15
12:03
(26) Спасибо! Темку можно закрыть.
28 Serginio1
 
23.09.15
12:07
Для примера сделал с minOccurs=""1""
    Объект=ФабрикаXDTO.Создать(ФабрикаXDTO.Тип("http:/Test5","Поставщик"));
    Объект.Продукция.Добавить("ОдинЭлемент");
    
    ЗаписьXML= новый ЗаписьXML;
    ЗаписьXML.УстановитьСтроку();
ФабрикаXDTO.ЗаписатьXML(ЗаписьXML,Объект);

Стр=ЗаписьXML.Закрыть();

ЧтениеXML= новый ЧтениеXML;
    ЧтениеXML.УстановитьСтроку(стр);
    
    
    Объект=ФабрикаXDTO.ПрочитатьXML(ЧтениеXML,ФабрикаXDTO.Тип(ЧтениеXML.URIПространстваИмен,ЧтениеXML.Имя));
    
    Сообщить(Объект.Продукция);


В отладчике показывает Объект.Продукция это строка.

Стоит добавить второй элемент
Объект.Продукция.Добавить("ВторойЭлемент");

И уже показывает
СписокXDTO
29 Serginio1
 
23.09.15
12:10
Но 1С генерит такую схему
<xs:schema xmlns:tns="http:/Test5" xmlns:xs="http://www.w3.org/2001/XMLSchema"; targetNamespace="http:/Test5" attributeFormDefault="unqualified" elementFormDefault="qualified">
    <xs:complexType name="Поставщик">
        <xs:sequence>
            <xs:element name="Продукция" type="xs:string" maxOccurs="unbounded"/>
        </xs:sequence>
    </xs:complexType>
</xs:schema>
30 Fragster
 
гуру
23.09.15
12:10
(28) я хз, что там у тебя в пакете. код (20) запускал? работает?
31 Fragster
 
гуру
23.09.15
12:11
убрал в коде minOccurs вообще. все равно список.
32 Serginio1
 
23.09.15
12:12
(30) Я сейчас добавлю в схему в 29 и проверю. Смысл то в тм, что 1С генерит такую схему при минимальном количестве 1
33 Serginio1
 
23.09.15
12:12
(31) Проверь 28
34 Serginio1
 
23.09.15
12:16
Кстати в отладчике показывает минимальное количество 1
35 Fragster
 
гуру
23.09.15
12:24
(33) ты забыл ЧтениеXML.ПерейтиКСодержимому();
36 Fragster
 
гуру
23.09.15
12:25
(35)+ и у тебя ФабрикаXDTO.Тип(ЧтениеXML.URIПространстваИмен,ЧтениеXML.Имя) из-за этого возвращает неопределено.
37 Serginio1
 
23.09.15
12:28
(35) Да она и так читает.
Твоя показыват список
Кстати строка такая
<Поставщик xmlns="http:/Test5" xmlns:xs="http://www.w3.org/2001/XMLSchema"; xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">;
    <Продукция>ОдинЭлемент</Продукция>
</Поставщик>

Сечас поставлю
(36) Я создал тип в тестовой конфигурации. Сейчас через файл сделаю
38 Serginio1
 
23.09.15
12:28
Но смысл в том, что 1С генерит при минимальном количестве схему 29. Проверь
39 Fragster
 
гуру
23.09.15
12:33
(38) все хорошо со схемой. на то, список это или объект - влияет maxOccurs. если там не 1, то будет список.
у тебя неправильно идет определение типа. вернее в него передаются неверные параметры. проверь в отладчике - если не сделать Чтение.ПерейтиКСодержимому(), то у тебя получается Фабрика.Тип("","");
40 Serginio1
 
23.09.15
12:38
(39) Посыпаю свою голову пеплом Забыл ЧтениеXML.ПерейтиКСодержимому();
41 D_Pavel
 
23.09.15
12:38
В общем проверил, minOccurs 0 не влияет.
42 Fragster
 
гуру
23.09.15
12:40
что-то я добрый сегодня. надо было в (12) и (14) вас обоих тыкать до просветления
43 Serginio1
 
23.09.15
12:49
(42) Еще раз прошу прощение и большое спасибо за поправку и добродушие. Просто давным давно работа с с сайтом на Asp.Net и там формировались классы как Object и при 1 элементе давали не массив а элемент. Это была такая реализация в Net. На 1С не проверял.
в 28 чтение происходило через AnyType
44 D_Pavel
 
23.09.15
12:54
(42) Я и так на (14) понял в чем собака порылась.
45 D_Pavel
 
23.09.15
13:04
-------Новый вопрос-------

как быть если файл прислали без указанного xmlns ?
46 D_Pavel
 
23.09.15
13:30
(45) Up
47 Serginio1
 
23.09.15
13:43
(45) Самому добавить
48 Serginio1
 
23.09.15
13:45
49 D_Pavel
 
23.09.15
13:50
(47) Строку просто заменить? Ок, годится.