|
Как удалить узел в XML файле по условию значения определенного атрибута? | ☑ | ||
---|---|---|---|---|
0
Alginsky
03.02.23
✎
23:22
|
Кто сталкивался с удалением атрибута в XML файле?
Есть такой XML: <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"> <Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings" Target="settings.xml"/> <Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/> <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering" Target="numbering.xml"/> <Relationship Id="rId6" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme" Target="theme/theme1.xml"/> <Relationship Id="rId5" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable" Target="fontTable.xml"/> <Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/webSettings" Target="webSettings.xml"/> <Relationship Id="rId7" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer" Target="footer1.xml"/> </Relationships> Надо удалить узел по условию если его атрибут "Type" равно http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer А сейчас это последний узел. Именно по этому условию нужно, по индексу не вариант, так как он может в любом месте списка быть... Возможно ли это реализовать? Через DOM или Чтение ЗаписьXML, главное не XDTO. Задача как обратный процесс для моей предыдущей темы: Недоступимое имя XML. Двоеточие в имени атрибута не принимает. |
|||
1
NorthWind
04.02.23
✎
08:34
|
Ну самое простое - зачитать чтением все подряд и тут же записывать записью, пока не встретите атрибут. Встретите - значит, не записывать.
|
|||
2
NorthWind
04.02.23
✎
08:36
|
ДОМ, по-моему, тоже дает возможность удалять узлы, но по сути там будет то же чтение и потом запись...
|
|||
3
eddy_n
04.02.23
✎
09:54
|
Как вариант использовать метод ДОМа УдалитьДочерний(). Это про узлы. Но - только на сервере.
|
|||
4
eddy_n
04.02.23
✎
09:55
|
Узел.УдалитьДочерний(ДочернийУзел); по твоему условию.
|
|||
5
ДедМорроз
04.02.23
✎
11:40
|
Дом грузить в память - иногда это будет смертельно для сервера - получите не хватает памяти.
Через SAX в 1с объект ЧтениеXML - читаем,а через запись сразу пишем. Нашли объект,который нужно удалить,выключаем запись,пока не дойдем до его закрытия. Если обнаружили открытый дочерний элемент,то просто пишем его в массив и ожидаем закрытие последнего элемента из массива - когда массив пуст,то включаем запись и продолжаем. Опять же,можно сделать массив вложенности элементов,если нас интересуют условия по родительским элементам. Получится быстро и просто даже на файлах,которые в память не помещаются. Я по такому принципу писал выборочное чтение файла обмена. |
|||
6
Alginsky
04.02.23
✎
12:17
|
(4) Да, видел этот метод, но как отобрать удаляемый узел? Вот это не смог сделать
|
|||
7
Alginsky
04.02.23
✎
12:23
|
(5) Я хотел через дом. Потому что с помощью Чтение Запись когда делаешь он удаляет пробелы в некоторых словах документа. Сравнил документы чтобы найти причину, оказалось метод Чтение Запись превращает такую строку - <w:t xml:space="preserve"></w:t> в такую - <w:t xml:space="preserve"/>, из-за этого удаляются пробелы. Есть ли решение для этого? Если есть тогда бы можно было рассмотреть метод который вы написали
|
|||
8
eddy_n
04.02.23
✎
13:07
|
(6) По имени найти - не вариант? НужныйЭлемент = ДокументDOM.ПолучитьЭлементыПоИмени("ТотСамыйЭлемент");
|
|||
9
eddy_n
04.02.23
✎
13:10
|
(8) Имя элемента заранее известно?
|
|||
10
eddy_n
04.02.23
✎
13:15
|
(8) Имя элемента заранее известно ?
|
|||
11
Alginsky
04.02.23
✎
13:39
|
(8) Не вариант, там везде же имя "Relationship" и именно по атрибуту "Type" этого элемента нужно отобрать
|
|||
12
eddy_n
04.02.23
✎
14:40
|
(11) Говоришь - обложили со всех сторон? Ну тогда - как в (1).
|
|||
13
kittystark
04.02.23
✎
15:54
|
тхт = новый ТекстовыйДокумент();
тхт.Прочитать( имяФайла ); стр = тхт.ПолучитьТекст(); стр = RegExpReplace( стр, <[^<]+footer[^<]+>", "" ); тхт.УстановитьТекст( стр ); тхт.Записать( имяФайла ); Function RegExpReplace( str, pattern, replacement ) export RegExp = new COMObject("vbscript.regexp"); RegExp.IgnoreCase = true; RegExp.MultiLine = true; RegExp.Global = true; RegExp.Pattern = pattern; return RegExp.Replace(str,replacement); EndFunction |
|||
14
kittystark
04.02.23
✎
15:58
|
поправочка, кавычку упустил
стр = RegExpReplace( стр, "<[^<]+footer[^<]+>", "" ); |
|||
15
kittystark
04.02.23
✎
16:06
|
а можно так
стр = RegExpReplace( стр, "<[^<]+footer[^>]+>", "" ); или так стр = RegExpReplace( стр, "<[^<]+schemas.openxmlformats.org\/officeDocument\/2006\/relationships\/footer[^>]+>", "" ); |
|||
16
ДедМорроз
04.02.23
✎
16:33
|
(7) тут проблема не в преобразователе,а в том,что такие преобразования по стандарту xml допустимы,и оба тега эквивалентны с точки зрения формата xml.
Если нужны пробелы,то их нужно в xml писать как &x20; тогда и преобразования не будет и согласно формату xml это будут значащие символы. |
|||
17
NorthWind
04.02.23
✎
16:53
|
(16) вообще, насколько я понял, тег xml:space как раз предназначен для того, чтобы парсер не удалял пробелы в начале и конце строки, чтобы не испортить форматирование, например, в стихах. https://www.w3.org/TR/xml/ Видимо, ТС имеет в виду что ломается как раз эта опция.
|
|||
18
NorthWind
04.02.23
✎
17:01
|
хотя как на это влияет сокращенное написание тега - не очень понятно. Если верить спецификации, парсер, встретив этот атрибут в элементе, должен поменять правила работы с пробелами для текущего элемента и для всех его потомков. И какая в сущности разница, используется ли сокращенное написание или полное?
|
|||
19
Архитектор_1С
04.02.23
✎
17:03
|
(0) Рекомендую эти свистопляски с XML-файлами делать через http-сервисы 1С, с которыми можно делать все что угодно в отличии от web-сервисов 1С
|
|||
20
Alginsky
04.02.23
✎
18:35
|
(19) так я эту функцию как раз через http-сервис использую, не знаю что вы имели ввиду под все что угодно...
Задача у меня такая: Разбираю docx файл, добавляю нижний колонтитул с QR кодом и текстом. С добавлением в docx где нет нижнего колонтитула без проблем работает, уже сделал. Теперь вторая задача у меня удалить нижний колонтитул если имеется, а потом добавить свой. Вот сейчас занимаюсь удалением ссылок старого колонтитула занимаюсь, а там вот такая труба с пробелами и с условными удалениями узла... |
|||
21
Alginsky
04.02.23
✎
18:36
|
(13) нее, Com не пойдет, все делается через http-сервис, модули все серверные
|
|||
22
kittystark
04.02.23
✎
19:06
|
(21) а ты попробуй
|
|||
23
Alginsky
04.02.23
✎
19:34
|
(22) так COM объекты только на клиенте работают же
Но все равно спасибо, на крайняк текстом мочить буду строки |
|||
24
kittystark
04.02.23
✎
19:42
|
я тут недавно боролся с XML помогите с XSLT - замена значения атрибута тэга - не получилось
но код приведенный мной - помог справиться, и поверь работает наСервере |
|||
25
NorthWind
04.02.23
✎
20:22
|
(20) так может лучше его не удалять, а очистить/подменить значения атрибутов?
|
|||
26
eddy_n
04.02.23
✎
20:42
|
(23) Заблуждение.
|
|||
27
eddy_n
04.02.23
✎
20:44
|
(23) Зарегь компоненту на серверу и работай себе там.
|
|||
28
eddy_n
04.02.23
✎
20:46
|
(24) И больше нигде ничего не пришлось менять? Только в одном тэге?
|
|||
29
Alginsky
04.02.23
✎
20:54
|
(16) (18) Нашел решение с проблемой пробелов(7), может кому понадобиться, лечиться одной строкой ЧтениеXML.ИгнорироватьПробелы = Ложь;
После этого не будет ломать пробелы |
|||
30
kittystark
04.02.23
✎
20:56
|
(28) да
там задача сводилась к тому, что в УПД для ЭДО поменять "статус - 2" на "статус - 1" но в той задаче код был такой стр = RegExpReplace( стр, "Функция\s*=\s*""ДОП""", "Функция=""СЧФДОП""" ); |
|||
31
eddy_n
06.02.23
✎
00:25
|
(29) Убедительный пример того, что надо просто читать мат. часть. Всё есть, надо только поднять.
|
|||
32
eddy_n
06.02.23
✎
02:44
|
(13) Чисто под Окна.
|
|||
33
RomaH
naïve
06.02.23
✎
10:16
|
xpath же?
|
|||
34
kittystark
06.02.23
✎
13:07
|
(33) научи!
и здесь и по ссылке в (24) |
|||
35
RomaH
naïve
06.02.23
✎
13:19
|
ну ... документДОМ
через xpath получаешь требуемые элементы - а дальше делаешь с ними всякое |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |