Имя: Пароль:
1C
1С v8
Недоступимое имя XML. Двоеточие в имени атрибута не принимает.
0 Alginsky
 
02.02.23
11:32
Доброго времени суток! Хочу добавить атрибут ("r:id") в document.xml, при записи документа пишет "Недоступимое имя XML".
Выяснил что нельзя указывать двоеточие в именах атрибута. В отладке подсмотрел, имена атрибутов с двоеточиями не указывается, вместо этого указывают "Префикс" атрибута и имя
Префикс = r, имя = id, по итогу получится нужное имя - "r:id"
Как этот префикс установить та?
Сам код:
///Document
        Чтение = Новый ЧтениеXML;
        Чтение.ОткрытьФайл(ВременнаяПапкаДляРазархивирования + "/word/document.xml");
        ПостроительDOM = Новый ПостроительDOM;
        ДокументDOM = ПостроительDOM.Прочитать(Чтение);
        Чтение.Закрыть();
        
        //создаем элемент и указываем у него 2 атрибута
         footerReference = ДокументDOM.СоздатьЭлемент("w:footerReference");
        footerReference.УстановитьАтрибут("r:id", "rId0");
         footerReference.УстановитьАтрибут("w:type", "default");
        
        ДокументDOM.ЭлементДокумента.ДобавитьДочерний(footerReference);
                
        Файл = Новый ЗаписьXML();
        Файл.ОткрытьФайл(ВременнаяПапкаДляРазархивирования + "/word/document_upd.xml", "UTF-8");
        
        ФайлDOM = Новый ЗаписьDOM();
        ФайлDOM.Записать(ДокументDOM, Файл);
        Файл.Закрыть();
        
        ПереместитьФайл(ВременнаяПапкаДляРазархивирования + "/word/document_upd.xml", ВременнаяПапкаДляРазархивирования + "/word/document.xml");
        УдалитьФайлы(ВременнаяПапкаДляРазархивирования + "/word/document_upd.xml");
        ///Document
1 Fragster
 
гуру
02.02.23
11:38
потому что у тебя должно быть пространство имен r и w и добавлять ты должен атрибуты без префикса, но в соответствующих пространствах имен. более того, сами буквы r и w не обязаны быть именно r и w, а являются просто ссылками к пространствам имен в корне.
2 Alginsky
 
02.02.23
11:44
(1) Я добавляю атрибут в существующий xml. Подскажите куда дописать пространство имен?
3 Гипервизор
 
02.02.23
12:00
(0) А почему не через ЗаписьXML?
4 eddy_n
 
02.02.23
12:00
(2) В каждом элементе его надо шлёпать.
5 eddy_n
 
02.02.23
12:02
(2) Пространство имен действует от точки объявления до конца элемента, где оно было объявлено.
6 Alginsky
 
02.02.23
12:03
(3) Пробовал через ЗаписьXML, через XDTO. Все они ломают исходный xml файл. Через Dom в остальные xml файлы добавил атрибуты, все идеально. Только вот с именами где двоеточие беда...
7 eddy_n
 
02.02.23
12:05
Есть нюанс: Пространства имен по умолчанию применяются только к элементам и не применяются к атрибутам.
8 Alginsky
 
02.02.23
12:06
(5) Подскажите здесь как быть. Добавляю в xml файле в узле w:sectPr:
w:sectPr w:rsidR="00F70D62" w:rsidRPr="00796320">
<w:footerReference w:type="default" r:id="rId0"/> <<---Такую строку надо добавить
<w:pgSz w:w="11906" w:h="16838"/>
<w:pgMar w:top="1134" w:right="850" w:bottom="1134" w:left="1701" w:header="708" w:footer="708" w:gutter="0"/>
<w:cols w:space="708"/>
<w:docGrid w:linePitch="360"/>
</w:sectPr>
9 Гипервизор
 
02.02.23
12:10
(6) Странно, а что именно ломается? Ну а всё-таки через ЗаписьXML получается добавить двоеточие?
10 Alginsky
 
02.02.23
12:20
(9) Структура ломается, c обычным методом ЧтениеXML ЗаписьXML полностью ломается структура, последовательность в хлам, как то сортирует непонятно что не xml а какой то файл из рандомных узлом появляется. А через XDTO тоже пробовал добавить и записать, там все ок, но также везде непонятные "xlmns" и т п строки добавляется... А при запаковке файла docx эти xml-ки становятся не читабельными
11 Гипервизор
 
02.02.23
12:24
(10) Странно, модифицировал xlsx через чтение и запись xml, такой проблемы не было.
12 Alginsky
 
02.02.23
12:27
(11) Есть ли пример где добавляли аналогичные атрибуты с такими именами?
13 Гипервизор
 
02.02.23
14:00
(12) Нет, увы, подобные атрибуты я не добавлял, я про сам факт ломки структуры файла.
14 Kassern
 
02.02.23
14:17
15 Alginsky
 
02.02.23
14:38
(14) нет, это есть. Как раз по sectPr надо добавить <w:footerReference w:type="default" r:id="rId0"/>
Но мне уже без разницы каким методом)) главное добавить
Получается так (8)
16 Alginsky
 
02.02.23
14:38
(15) Под sectPr*
17 Alginsky
 
02.02.23
14:49
Для примера, есть минимальный файл document.xml https://disk.yandex.kz/d/vCu_16BqtiUUfA
туда под узел "w:sectPr w:rsidR="00F70D62" w:rsidRPr="00796320">" надо добавить эту строку - <w:footerReference w:type="default" r:id="rId0"/>
такая тупая задача, и так и так пробую уже нет вариантов
18 Ivan_495
 
02.02.23
14:52
а xsd где?
19 Alginsky
 
02.02.23
14:56
(18) сорри, пакеты грохнул когда не смог с XDTO методом
20 Alginsky
 
02.02.23
15:11
Это вот код который через Чтение и Запись делает. Если ниче не добавляешь то норм сохраняет оказывается. В разные места пихал свой код "Если Файл.Имя = "w:sectPr" Тогда Добавляю свои атрибуты. Куда пристроить это условие добавление своих атрибутов?            

                Файл = Новый ЧтениеXML;
        Файл.ОткрытьФайл(ВременнаяПапкаДляРазархивирования + "/word/document.xml");
        

        ЗаписьXML=Новый ЗаписьXML;
        ЗаписьXML.ОткрытьФайл(ВременнаяПапкаДляРазархивирования + "/word/document_upd.xml");
        ЗаписьXML.ЗаписатьБезОбработки("<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?>");
        
        счетчик=0;
        
        Пока Файл.Прочитать() Цикл
            счетчик=счетчик+1;        
            Если Файл.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
                
                ЗаписьXML.ЗаписатьНачалоЭлемента(Файл.Имя);
                
                Пока Файл.ПрочитатьАтрибут() Цикл
                    ЗаписьXML.ЗаписатьАтрибут(Файл.Имя,Файл.Значение);
                КонецЦикла;
                
            КонецЕсли;
            
            Если Файл.ТипУзла = ТипУзлаXML.Текст Тогда
                ЗаписьXML.ЗаписатьТекст(Файл.Значение);
            КонецЕсли;
            
            Если Файл.ТипУзла = ТипУзлаXML.КонецЭлемента Тогда
                ЗаписьXML.ЗаписатьКонецЭлемента();
            КонецЕсли;
                            
            
        КонецЦикла;
        
        Файл.Закрыть();         
        ЗаписьXML.Закрыть();
        ПереместитьФайл(ВременнаяПапкаДляРазархивирования + "/word/document_upd.xml", ВременнаяПапкаДляРазархивирования + "/word/document.xml");
        УдалитьФайлы(ВременнаяПапкаДляРазархивирования + "/word/document_upd.xml");
21 Alginsky
 
02.02.23
15:14
Например вот, куда его встроить в коде Чтение Запись?
                          Если Файл.Имя = "w:sectPr" Тогда
                                        ЗаписьXML.ЗаписатьНачалоЭлемента("w:footerReference");
                                        ЗаписьXML.ЗаписатьАтрибут("w:type", "default");
                    ЗаписьXML.ЗаписатьАтрибут("r:id", "rId0");
                    ЗаписьXML.ЗаписатьКонецЭлемента();
                          КонецЕсли;
22 arsik
 
гуру
02.02.23
15:15
(20) Это ты какую то херню сделал.
23 Alginsky
 
02.02.23
15:20
(22) ну это как бы копирование проще говоря, по плану при его формировании надо запихнуть свое Имя с атрибутами (21) . А какие варианты есть?
24 Ivan_495
 
02.02.23
15:21
ищи xsd и по нему формируй, с xdto тренинурйся
25 Alginsky
 
02.02.23
15:25
(24) Я с XDTO разобрался и попробовал, там он добавляет какие то параметры: xmlns и всякие которые не должны быть там. На форумах пишут что с помощью XDTO не уберешь
26 eddy_n
 
02.02.23
16:26
(25) Накатить ЗаписьXML в текстовый документ
ТекстДок.УстановитьТекст(ЗаписьXML.Закрыть());
Естественно сохранять не нужно.
А потом уже через СтрНайти и СтрЗаменить поработать с XSD Namespaces.
Так будет проще всего, на мой взгляд.
27 eddy_n
 
02.02.23
16:28
(26) от XDTO отходить не стоит, на мой взгляд.
28 Ivan_495
 
02.02.23
17:08
(25) сервис тестировал?
29 Kassern
 
02.02.23
17:18
30 Kassern
 
02.02.23
17:19
(29) Если да, то "<w:footerReference w:type="default" r:id="rId0"/>" - "w:footerReference" - Имя нового элемента, w:type="default" - имя/значение в УстановитьАтрибут. "r:id="rId0"" - тоже самое.
31 Kassern
 
02.02.23
17:22
(30) УстановитьАтрибут->ЗаписатьАтрибут
32 Alginsky
 
02.02.23
17:24
(29) (30) (31) Да да, мне как раз аналогично надо сделать. Что то не допер, это надо в варианте Чтение Запись добавить?
33 Kassern
 
02.02.23
17:41
(32) Я же вам расписал в (30)
    ЗаписьXML.ЗаписатьНачалоЭлемента("w:footerReference");
    ЗаписьXML.ЗаписатьАтрибут("w:type","default");
    ЗаписьXML.ЗаписатьАтрибут("r:id","rId0");
    ЗаписьXML.ЗаписатьКонецЭлемента();
34 eddy_n
 
02.02.23
17:51
Вот этот момент я не понял:
Если Файл.Имя = "w:sectPr". Это как?
35 Kassern
 
02.02.23
17:59
(34) Потому что нужно давать нормальные имена переменным)
Файл = Новый ЧтениеXML;  -> ЧтениеXML = Новый ЧтениеXML;
36 Alginsky
 
02.02.23
18:07
(33) Да, спасибо, я понял этот момент. Вот в какое место его запихнуть интересно. То есть как мне определить что я в цикле оказался в sectPr, вот этот момент нужен. Нужно же именно в sectPr добавит, из-за этого написал Если Файл.Имя = "w:sectPr"… (21) здесь я уже писал про (33)
37 Alginsky
 
02.02.23
18:07
(35) даа, сорри это копипаст))
38 eddy_n
 
02.02.23
18:09
Если ЧтениеФайл.ТипУзла = ТипУзлаXML.НачалоЭлемента И ЧтениеФайл.Имя="w:sectPr" Тогда
39 Alginsky
 
02.02.23
19:36
(38) Я вот это условие с кодом "w:footerReference"... не могу определить в какое место запихнуть... В этом вся проблема

Там мой "w:footerReference"... либо до sectPr добавляется если добавить условие до цикла Файл.ПрочитатьАтрибут(), либо затирает атрибуты если добавить после Файл.ПрочитатьАтрибут()

<w:sectPr w:rsidR="00624DDD" w:rsidRPr="00D23EF3"> <--Вот эти атрибуты затираются.
А если добавить условие после цикла атрибутов -  Пока Файл.ПрочитатьАтрибут() Цикл
                    ЗаписьXML.ЗаписатьАтрибут(Файл.Имя,Файл.Значение);
                КонецЦикла;
то он вообще не отрабатывается.
40 Kassern
 
02.02.23
19:46
(36) "от в какое место его запихнуть интересно". Все же на картинке видно в (29)
Синим отмечены элементы, значения атрибутов - зеленым. Вам нужно после окончания элемента w:p вставить свой w:footerReference
41 Alginsky
 
02.02.23
19:49
В общем добавил по условию:
                        Если Файл.ТипУзла = ТипУзлаXML.НачалоЭлемента И Файл.Имя="w:pgSz" Тогда
                ЗаписьXML.ЗаписатьНачалоЭлемента("w:footerReference");
                ЗаписьXML.ЗаписатьАтрибут("w:type","default");
                ЗаписьXML.ЗаписатьАтрибут("r:id","rId0");
                ЗаписьXML.ЗаписатьКонецЭлемента();
            КонецЕсли;
Получается над <w:pgSz w:w="11907" w:h="16839"/> добавился, а это как раз нужное место. Но xml сломался, при открытии через браузер пишет:
"error on line 6832 at column 51: Namespace prefix r for id on footerReference is not defined"
42 Alginsky
 
02.02.23
20:11
(41) Понял, надо добавить xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
Спасибо большое ребята!
43 Kassern
 
03.02.23
10:46
(42) ага, у вас не было описания пространства
44 Fragster
 
гуру
03.02.23
11:32
я про пространства ещё в (1) написал
45 Fragster
 
гуру
03.02.23
11:33
а еще то, что r и w прям нифига не фиксированные значения могут быть
46 Fragster
 
гуру
03.02.23
11:37
и добавлять надо так: УстановитьАтрибут(<URIПространстваИмен>, <ЛокальноеИмя>, <Значение>)
47 Fragster
 
гуру
03.02.23
11:41
локальное имя - это то, что после двоиточия
48 Fragster
 
гуру
03.02.23
11:41
или двоеточия
49 eddy_n
 
03.02.23
13:20
(46) +1. Однозначно.
Глупец, лишенный способности посмеяться над собой вместе с другими, не сможет долго выносить программирование. Фредерик Брукс-младший