![]() |
Поиск <строки> в XML
В файле надо найти строку, например:
<WIDTH int="800" /> и заменить её на <WIDTH int="1024" /> Но лучше найти с неизвестным значением. Я думаю здесь можно пропарсить по открытию тега "<" плюс имя "WIDTH int=" и собственно по закрытию /> И перезаписать найденный шаблон строки. Нечто такое, только без ошибок можно? Код:
$file = FileOpen("C:\I\WinSxS\Process\Application Data\codeblocks\default.conf",0) Файл собой представляет типичный XML Здесь мы уже решали однажды проблему, но там обошлось хитростью с IniWright. Но тут это врядли поможет. Кстати, может кто знает что за файл лежит system32\xmlparser.exe Может этим как-то можно пользоваться для такой задачи? Самое главное чуть не забыл, я именно хотел организовать побайтное сравнение, чтобы найти начало строки. И потом если начало найдено, то найти и сравнить строку итд... Иначе если с помощью ReadFile читать, то можно наткнуться на пробелы и отступы итп. Вообщем я думаю надо искть "<" и ">", а потом дополнительно парсить то что внутри. Скорость работы скрипта вообщем-то не важно. Помогите такой скрипт зделать? Или какие идеи есть ещё. :) |
Цитата:
Код:
$sFile = "C:\I\WinSxS\Process\Application Data\codeblocks\default.conf" |
Спасибо большое, очень полезный скрипт! Некоторые программы не используют реестр, так к ним не подобраться без этого было! :)
А можно как-то многостроковые блоки выхватывать из XML, так как я боюсь что такое мне тоже наверняка встретится. Я имею ввиду где начало "<" и завершение "/>" внутри содержат @CRLF строчки? Искать по контенту, например, найти: "<FFFF" конец будет само собой первый попавшийся тэг "/>" |
Если файл действительно содержит xml, то и работать с ним можно и нужно теми же средствами: Сценарии объектной модели документа DOM XML средствами OLE-Automation.
|
Цитата:
...либо используйте DOM, как подсказал Iska ... :) Цитата:
Iska, увы, далеко не всегда доступна полная инфа о структуре документа - чаще есть только несколько примеров, на основе которых приходится строить свои предположения о возможной структуре |
Код:
$sFile = @AppDataDir & "\codeblocks\default.conf" Цитата:
Цитата:
Это скорее для html аддонов инструкции, причём которые пишут, на м же надо их удалённо-пакетно править налету :) ? ЗЫ Идея налету родилась! А что если вывести StringRegExpReplace() в STDINPUT консоли, зделать типа утилиту! ))) Я понимаю есть всякие PERL итп. но чисто поэкспереминтировать? Или это сложный и бажистый скрипт получиться? Я имею ввиду зделать (AutoIt) StringRegExpReplace.exe --help :) |
Цитата:
|
amel27, при возможности напиши пример "<SOMETHING" & @CRLF & "/>",
а я потом подумаю как применять, в любом случае пригодиться такое. Но я сам тоже подумаю может и сам справлюсь. Про vbs спасиб! Теперь ясно! Кстати, говоря vbs могут не работать из-за всяких твиков системы, а autoit даже от себя не заввисим! :) |
Цитата:
|
Для работы с xml есть библиотека: XML DOM wrapper (COM).
|
Цитата:
Код:
<gcc> Здесь можно лишь сложить все теги <gcc> + <NAME> + <str> + <![CDATA[GNU GCC Compiler]]> ... + <MASTER_PATH> + <str> + <![CDATA[C:\Program Files\mingw32]]> игнорируя табуляцию и пробелы... либо удалив их либо установив свою произвольную табуляцию, чтобы отредактировать этот блок автоитом. Наверное это сложная задача, но может от того и интереснее. И тогда уже не будет непроходимых XML-ов! :) |
Вот так можно получить данные:
Код:
#include <_XMLDomWrapper.au3> Код:
_XMLSetValue("Test.xml", "gcc/MASTER_PATH/str", "D:\Other\mingw32") |
semiono, как-то так:
Код:
$sFile = "1.xml" |
amel27, невозможно использовать переменные, sRExp удаляет слеши в пути:
$sText = StringRegExpReplace($sText, $sRExp, "$1"& @ProgramFilesDir &"\\mingw32$3") А без переменных ничего хорошего не напишешь, надо что-то придумать тут! Я в паттернах не шарю, сам не смогу поправить. Кстати, не очень понятно зачем надо \ фильтровать, ведь в шаблоне файла только прямые / слеши? Или это фитча в StringRegExpReplace() |
Цитата:
Код:
$sText = StringRegExpReplace($sText, $sRExp, "$1"& StringReplace(@ProgramFilesDir, "\", "\\") &"\\mingw32$3") |
Цитата:
А вот сейчас хороший вариант! :) Ой, стоп! Я не понял, я думал это не рабочий пример... Цитата:
|
Я извиняюсь, вот ещё один пример реальный надо доделать. И тему можно закрыть.
Код:
<bcc> Я бы сам тупо зделал три прохождения одного блока, но наверное есть способ лучше? Должно быть так: 1. @SystemDir & "\include" 2. @SystemDir & "\lib;" & @SystemDir & "\lib\psdk" 3. @SystemDir И спасибо ещё раз!!! |
Цитата:
Код:
_XMLSetValue("Test.xml", "bcc/INCLUDE_DIRS/str", @SystemDir & "\include") |
Пример.
Код:
<!-- ArrangeWindow --> <int name="H" value="1024"/> <int name="V" value="768"/> Значения должны быть таковы - @DesktopWidth, @DesktopHeigh. Просмотрел весь файл, практически схема повторяется одна и та же. <int name="..." value="..."/> <float name="..." value="..."/> итд. Все заголовки вида <!-- ArrangeWindow --> , кажись это коментарий так пишется в XML. Мне очень нужно скрипт под этот XML. :( Creat0R, я не уверен пойдёт ли то, что ты написал без изменений? Func _XMLSetValue($sFile, $sPath, $sValue) ... Мне тяжело расшифровать StringRegExpReplace() паттерн, может там даже лишнее или не хватает чего? Помоги под эту задачу, покажи как должно быть? Кстати, скачал _XMLDomWrapper.au3 долго глядел в него, но без справки вообще ловить нечего. Возможно там _XMLUpdateField как-то работает с полями XML, но не ясно, что именно делать :) |
Я тут смотрю, в качестве заголовка идёт такое
<obj class="UPoint" name="Size" ID="182564128"> Однако ID="182564128" может изменяться, поэтому его значение надо игнрировать. Вобщем нужен шаблон чтобы привести к такому виду грубо говоря <!-- ArrangeWindow --> (это тоже должно быть, ато там и другие секции есть) ... начало: <obj class="UPoint" name="Size" ID="????"> <int name="H" value="@DesktopHeight"/> <int name="V" value="@DesktopWidth"/> конец: </obj> По-моему код может быть таким - Рид файл компаре стринг иф <!-- ArrangeWindow --> = 1 тогда компаре стринг итд. сравниваем строки и двигаемся вперёд. ?? :) |
Цитата:
Код:
$sFile = @DesktopDir & "\Test.xml" |
Большое спасибо!
А глобальный заголовок проверить? <!-- ArrangeWindow --> .... <obj class="UPoint" name="Size" ID="182564128"> <int name="H" value="1152"/> <int name="V" value="864"/> </obj> ... <!-- Event Image --> ... <!-- Enable Record on Select Track --> .... <!-- Registration --> ...итд Без этого не получится к сожалению. Может через If EndIf как-то? Цитата:
|
$sData = FileRead($sFile)
If StringInStr($sData, "<!-- ArrangeWindow -->") <> 0 Then $sData = StringRegExpReplace(... Кажись работает! Только наверное не совсем правильно? |
Цитата:
|
Нет, не работает.
Если две секции <!-- ArrangeWindow --> ... <!-- Event Image --> ... то StringRegExpReplace() работает всегда с последней секцией. StringInStr просто проверяет весь файл на наличие <!-- ArrangeWindow --> А вот как зделать чтобы обрабатывался именно блок <!-- ArrangeWindow --> http://forum.oszone.net/post-1544021-19.html Зацепка только одна, то что в конце всегда стоит безымянный тэг </item> |
Цитата:
Код:
$sData = StringRegExpReplace($sData, '(?si)(<!-- ArrangeWindow -->.*?<obj.*name="Location".*?>.*?(?!</obj>)<int name="H" value=")\d*("/>)', '${1}' & $sHValue & '$2') |
Creat0R, спасибо! Мне этого скрипта хватит, просто надо было доделать, очень нужно было позарез.
XML очень непроходимый, поэтому я условия не сразу учёл, и даже удивился, два текста встретились, и оба совершенно различной структуры! При такой любви производителей к xml, и неудосужились внедрить winapi для работы с этим в винду. :search: |
semiono,
Тема решена? |
Тема решена. :(
Мне стыдно, я вдруг вспомнил это я сам коментарии писал давно очень и забыл: <!-- ArrangeWindow --> <!-- Event Image --> итп. это действительно были коменты, причём от меня )) Структура файла: ... <item> <string name="Group" value="PArrangeWindow"/> ... <obj class="UPoint" name="Location" ID="182867016"> <int name="H" value="0"/> <int name="V" value="0"/> </obj> ... <obj class="UPoint" name="Size" ID="182564128"> <int name="H" value="1132"/> <int name="V" value="732"/> </obj> ... </item> ... Но уже тему закрою, сам виноват, надо было вовремя разбираться. |
Время: 14:55. |
Время: 14:55.
© OSzone.net 2001-