Форум программистов, компьютерный форум, киберфорум
Наши страницы
Batch (CMD/BAT)
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.73/11: Рейтинг темы: голосов - 11, средняя оценка - 4.73
Sergck
0 / 0 / 0
Регистрация: 30.01.2015
Сообщений: 3
1

Замена параметра в XML-файле

30.01.2015, 17:27. Просмотров 2162. Ответов 19
Метки нет (Все метки)

Добрый день, можно поднять такой вопрос. Есть много xml файлов, нужно заменить один параметр на имя документа.
Формат файла вот такой.
Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
      <C_DOC_SUB>010</C_DOC_SUB>
        <C_DOC_VER>7</C_DOC_VER>
        <C_DOC_TYPE>0</C_DOC_TYPE>
        <C_DOC_CNT>1</C_DOC_CNT>
        <C_REG>23</C_REG>
        <C_RAJ>1</C_RAJ>
        <PERIOD_MONTH>01</PERIOD_MONTH>
        <PERIOD_TYPE>1</PERIOD_TYPE>
        <PERIOD_YEAR>2015</PERIOD_YEAR>
        <C_STI_ORIG>2301</C_STI_ORIG>
        <C_DOC_STAN>1</C_DOC_STAN>
        <D_FILL>20012015</D_FILL>
    </DECLARHEAD>
    <DECLARBODY>
        <HCOPY>1</HCOPY>
        <HFILL>20012015</HFILL>
        <HNUM>200</HNUM>.........
Задача состоит в том что бы взять значение <HNUM> (в нашем примере 200) и вставить его вместо <C_DOC_CNT> (в нашем примере 1).

Как этом можно сделать с помощью командной строки? и вообще такое возможно?
Просто очень много файлов, больше сотни, не хотелось бы руками это делать.
параметр <C_DOC_CNT> во всех файлах один и тот же - 1
А вот <HNUM> разный.
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
30.01.2015, 17:27
Ответы с готовыми решениями:

Замена символов в XML-файле
Имеется: файлы *.xml в одну строку Необходимо: найти закрытие тега и...

Замена строк в XML-файле
имеются XML файлы нужно через командную строку заменить &lt;Иные&gt;...

Замена символов в XML-файле
Задача такая: есть файл xml, в котором есть строки: &lt;tag&gt;&lt;!]&gt;&lt;/tag&gt; &lt;tag...

Замена даты в XML-файле
Добрый день. Есть xml файл, в котором имеются строки вида:...

Поиск в реестре параметра и замена его значения
Добрый день! А подскажите, как сделать так: Нужно, чтобы находило параметр...

19
ComSpec
3407 / 1951 / 628
Регистрация: 26.02.2014
Сообщений: 1,457
31.01.2015, 16:37 2
Sergck,
1) если все Ваши файлы находятся непосредственно в одной папке,
2) если в условии задачи нет никаких неопределённостей,
3) если приведённый Вами фрагмент контента XML-файла соответствует реальности,
то попрбуйте такой вариант кода:


Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@echo off& setlocal enableextensions
 
set "folder=D:\Test"
set "files=*.xml"
set "from=<HNUM>.*</HNUM>"
set "to=<C_DOC_CNT>?</C_DOC_CNT>"
set "?=1"
 
pushd "%folder%"
for /f "delims=" %%i in ('"2>nul dir/a-d/b "%files%""') do (
 for /f "delims=%from% " %%j in ('findstr/irc:"^ *%from%" "%%i"') do (
  for /f %%k in ('^<"%%i" find/c /v ""') do @<"%%i">$ (
   for /l %%l in (1 1 %%k) do @(
    set/p x=
    if defined x (cmd/v/c "if "!x: =!" equ "!to:?=%?%!" (echo !x:%?%=%%j!) else (echo.!x!)") else (echo.)
    set x=
    )
   )
  )
 >nul move $ "%%i"
 )
popd
 
endlocal& exit/b 0

.



Тестируйте пакетный файл на копии папки, поскольку мало ли что мы с Вами не учли!
1
volodin661
1866 / 924 / 154
Регистрация: 10.12.2013
Сообщений: 3,099
31.01.2015, 20:32 3
Лучший ответ Сообщение было отмечено Sergck как решение

Решение

1.xml
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?xml version="1.0" encoding="UTF-8"?>
<ROOT>
<DECLARHEAD>     
        <C_DOC_SUB>010</C_DOC_SUB>
        <C_DOC_VER>7</C_DOC_VER>
        <C_DOC_TYPE>0</C_DOC_TYPE>
        <C_DOC_CNT>1</C_DOC_CNT>
        <C_REG>23</C_REG>
        <C_RAJ>1</C_RAJ>
        <PERIOD_MONTH>01</PERIOD_MONTH>
        <PERIOD_TYPE>1</PERIOD_TYPE>
        <PERIOD_YEAR>2015</PERIOD_YEAR>
        <C_STI_ORIG>2301</C_STI_ORIG>
        <C_DOC_STAN>1</C_DOC_STAN>
        <D_FILL>20012015</D_FILL>
</DECLARHEAD>
<DECLARBODY>
        <HCOPY>1</HCOPY>
        <HFILL>20012015</HFILL>
        <HNUM>200</HNUM>
</DECLARBODY>
</ROOT>
1.xsl

XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" encoding="UTF-8"/>
 
<!-- This is an identity template - it copies everything
         that doesn't match another template -->
<xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
</xsl:template>
   
       
<xsl:template match="C_DOC_CNT">
    <xsl:element name="C_DOC_CNT">
        <xsl:value-of select="//DECLARBODY/HNUM" />    
    </xsl:element>
 
</xsl:template>
 
 
</xsl:stylesheet>
Преобразование с помощью msxsl.exe

Bash
1
msxsl 1.xml 1.xsl -o 2.xml
2.xml
Кликните здесь для просмотра всего текста

XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?xml version="1.0" encoding="UTF-8"?>
<ROOT>
<DECLARHEAD>     
        <C_DOC_SUB>010</C_DOC_SUB>
        <C_DOC_VER>7</C_DOC_VER>
        <C_DOC_TYPE>0</C_DOC_TYPE>
        <C_DOC_CNT>200</C_DOC_CNT>
        <C_REG>23</C_REG>
        <C_RAJ>1</C_RAJ>
        <PERIOD_MONTH>01</PERIOD_MONTH>
        <PERIOD_TYPE>1</PERIOD_TYPE>
        <PERIOD_YEAR>2015</PERIOD_YEAR>
        <C_STI_ORIG>2301</C_STI_ORIG>
        <C_DOC_STAN>1</C_DOC_STAN>
        <D_FILL>20012015</D_FILL>
</DECLARHEAD>
<DECLARBODY>
        <HCOPY>1</HCOPY>
        <HFILL>20012015</HFILL>
        <HNUM>200</HNUM>
</DECLARBODY>
</ROOT>



утилиту msxsl скачивать отсюда
http://www.microsoft.com/en-us/download/details.aspx?id=21714
0
Sergck
0 / 0 / 0
Регистрация: 30.01.2015
Сообщений: 3
06.02.2015, 18:09  [ТС] 4
volodin661
А подскажите, пожалуйста как это можно применить когда много файлов?
А то в ручную запускать когда файлов так штук 100. Не очень. Хотя проверил на одном то работает, текст заменяет.

Добавлено через 11 минут
ComSpec,

Этот вариант не получает. Пишет ошибку
Bash
1
2
Environment variable local enableextensions  not defined
The system cannot find the file specified.
Все делал в папке - Test

Больше не чего делать в файле не надо.
Вот пример файлика http://x.megastyle.com/dl.php?dl_id=...cf3dd571f3a04c

С батником конечно было бы удобно когда много файлов и нужно их все обработать.
0
volodin661
1866 / 924 / 154
Регистрация: 10.12.2013
Сообщений: 3,099
06.02.2015, 19:24 5
Лучший ответ Сообщение было отмечено Sergck как решение

Решение

Sergck,

а как же творческий подход?

1.bat

1C
1
2
3
@mkdir saved-xml
@copy *.xml saved-xml\
for %%x in ( *.xml  ) do @msxsl %%x 1.xsl -o %%x
Добавлено через 35 минут
1.bat: пункты 1 и 2 - для одного запуска (подстраховка)
0
ComSpec
3407 / 1951 / 628
Регистрация: 26.02.2014
Сообщений: 1,457
07.02.2015, 02:55 6
Цитата Сообщение от Sergck Посмотреть сообщение
С батником конечно было бы удобно когда много файлов и нужно их все обработать.

Раз "батник", так "батник":
Bash
1
@powershell "ls -file|?{$_.extension-eq'.xml'}|%%{($x=[xml](gc($y=$_.fullname))).SelectSingleNode('//C_DOC_CNT').InnerText=$x.SelectSingleNode('//HNUM').InnerText;$x.save($y)}"
.
Положить в папку с обрабатываемыми XML-файлами и запустить.
0
Sergck
0 / 0 / 0
Регистрация: 30.01.2015
Сообщений: 3
07.02.2015, 03:15  [ТС] 7
ComSpec,
Получаю вот такое сообщение
Bash
1
2
3
4
5
6
7
8
9
10
Get-ChildItem : Не удается найти параметр, соответствующий имени параметра "fil
e".
строка:1 знак:9
+ ls -file <<<< |?{$_.extension-eq'.xml'}|%{($x=[xml](gc($y=$_.fullname))).Sele
ctSingleNode('//C_DOC_CNT').InnerText=$x.SelectSingleNode('//HNUM').InnerText;$
x.save($y)}
    + CategoryInfo          : InvalidArgument: (:) [Get-ChildItem], ParameterB
   indingException
    + FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Comm
   ands.GetChildItemCommand
Добавлено через 2 минуты
volodin661,

Спасибо. Огромнейшее!!! Очень помогло и сэкономил кучу времени на рутину работу. Сработал такой вариант и прошла замена.
0
Furee
0 / 0 / 0
Регистрация: 10.12.2016
Сообщений: 10
27.12.2016, 18:29 8
Подскажите пожалуйста, не могу разобраться.
Как, используя этот пример, записать определенный параметр из одного .xml файла в другой без излишних сравнений (просто нагло заменить его)?
Делаю так и получаю нужное значение:
Windows Batch file
1
2
3
4
5
6
7
set "MYIDSource=d:\source_file.xml"
set "MYIDDest=d:\dest_file.xml"
set "from=<MYID>.*</MYID>"
set "to=<MYID>?</MYID>"
 
for /f "delims=" %%a in ("%MYIDSource%") do (
    for /f "delims=%from% " %%b in ('findstr/irc:"^ *%from%" "%%a"') do
Что дальше делать? Как его вставить в to?
0
volodin661
1866 / 924 / 154
Регистрация: 10.12.2013
Сообщений: 3,099
27.12.2016, 20:43 9
если Windows 7 и выше, то наилучший инструмент для автоматизированного XML-редактирования - powershell.
1
Furee
0 / 0 / 0
Регистрация: 10.12.2016
Сообщений: 10
27.12.2016, 21:15 10
volodin661,
Спасибо за совет!
Дело в том, что .xml файл возможно будет обрабатываться этой командой не только на Win7+, но и XP, Serv.2003, так что скрипт должен быть готов к этому.
0
volodin661
1866 / 924 / 154
Регистрация: 10.12.2013
Сообщений: 3,099
28.12.2016, 02:51 11
Цитата Сообщение от Furee Посмотреть сообщение
так что скрипт должен быть готов к этому.
ну, наши скрипты - они ого-го..
ко всему готовы.

и шо, вот эти 2003 и XP - они не в сети, неуправляемы ?
0
Furee
0 / 0 / 0
Регистрация: 10.12.2016
Сообщений: 10
28.12.2016, 03:07 12
Цитата Сообщение от volodin661 Посмотреть сообщение
наши скрипты - они ого-го..
Не сомневаюсь! ))
Цитата Сообщение от volodin661 Посмотреть сообщение
и шо, вот эти 2003 и XP - они не в сети, неуправляемы ?
Да там все не так просто. )) Они то управляемы, но нужна автоматизация процесса и, пока что, именно через bat-ник.
Скрипт предназначается для подстановки определенного параметра в .xml файл из другого .xml файла (при чем этот параметр находится в разных по номеру строках), что в последствии обеспечит правильную работу конкретного приложения.
0
volodin661
1866 / 924 / 154
Регистрация: 10.12.2013
Сообщений: 3,099
28.12.2016, 03:28 13
постановка задачи должна быть точнее.

это единичный случай ?
рассматриваемые XML с переводом строки или нет ?
рассматриваемые XML в какой кодировке?
какого размера рассматриваемые XML?
что означает фраза 'именно через батник' - нельзя пользоваться ничем кроме того, что уже установлено на данных Виндовс?
0
Furee
0 / 0 / 0
Регистрация: 10.12.2016
Сообщений: 10
28.12.2016, 04:12 14
Цитата Сообщение от volodin661 Посмотреть сообщение
постановка задачи должна быть точнее.
Дык я как бы на основе первого поста задавал вопрос. Просто думал, что там и так уже задача объяснена... а у меня случай выходит похожий, с небольшим отличием только в том, что мне надо один и тот же параметр обрабатывать в цикле.

По Вашим вопросам:
1. Нет.
2. Нет.
3. ANSI.
4. Source ~ 1kb (10-20 строк);
Dest ~3kb (85-100 строк).
5. Целевые машины будут разными и с неизвестным набором инструментов, но 100% везде винда, которая способна обработать батник.

Ну вот как-то так.
0
volodin661
1866 / 924 / 154
Регистрация: 10.12.2013
Сообщений: 3,099
28.12.2016, 05:36 15
Цитата Сообщение от Furee Посмотреть сообщение
Дык я как бы на основе первого поста задавал вопрос.
природная скромность мне не позволяла спросить,
чем же тогда не устроило решение от volodin661 #3, которое заслужило слёзную благодарность автора 1-го поста?

Добавлено через 5 минут
цена вопроса - скопировать в system32 утилитку msxsl.exe 25K, скачанную с сайта microsoft
0
Furee
0 / 0 / 0
Регистрация: 10.12.2016
Сообщений: 10
29.12.2016, 04:57 16
Победил! )) Вопрос снимаю.
Windows Batch file
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
set "folder=d:\Source"
set "MYIDSource=Source_file.xml"
set "MYIDDest=Destination_file.xml"
set "from=<MYID>.*</MYID>"
set "to=<MYID>?</MYID>"
set "?=test_phrase"
 
pushd "%folder%"
for /f "delims=" %%a in ("%MYIDSource%") do (
  for /f "delims=%from% " %%b in ('findstr/irc:"^ *%from%" "%%a"') do (
    for /f "delims=" %%c in ("%MYIDDest%") do (
      for /f "delims=%from% " %%d in ('findstr/irc:"^ *%from%" "%%c"') do (
        for /f %%e in ('^<"%%c" find/c /v ""') do @<"%%c">$ (
          for /l %%d in (1 1 %%e) do @(
            set/p x=
             if defined x (cmd/v/c "if "!x: =!" equ "!to:?=%?%!" (echo !x:%?%=%%b!) else (echo.!x!)") else (echo.)
            set x=
            )
          )
        >nul move $ "%%c"
      )
    )
  )
)
popd
volodin661,
Спасибо, я попробую Ваш вариант тоже, только немного позже.

Добавлено через 12 часов 4 минуты
Еще один вариант. Немного поменял и упростил скрипт. Может кому пригодится.
Теперь он меняет не конкретно заданный статический параметр (как это было set "?=test_phrase") , а любой найденный в этом заданном месте на требуемый, который берется из другого файла в таком же месте.
Это как раз именно то, что мне надо было.
Windows Batch file
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@echo off
SetLocal EnableExtensions
 
set "MYIDSource=C:\Source_File.xml"
set "MYIDDest=C:\Destibation_File.xml"
set "between=<MYID>.*</MYID>"
 
for /f "delims=%between% " %%a in ('findstr/irc:"^ *%between%" "%MYIDSource%"') do (
  for /f "delims=%between% " %%b in ('findstr/irc:"^ *%between%" "%MYIDDest%"') do (
    for /f %%c in ('^<"%MYIDDest%" find/c /v ""') do @<"%MYIDDest%">$ (
      for /l %%d in (1 1 %%c) do @(
        set/p x=
          if defined x (cmd/v/c "if "!between: =!" equ "!between:%%b=%%b!" (echo !x:%%b=%%a!) else (echo.!x!)") else (echo.)
        set x=
        )
      )
    >nul move $ "%MYIDDest%"
  )
)
 
endlocal && exit/b 0
Спасибо форуму за помощь!

Добавлено через 9 часов 59 минут
Столкнулся с интересной проблемой, объясните пожалуйста, если кто знает как решить.
В общем такое дело: при использовании последнего скрипта, не вытаскивается параметр из .xml файла если в нем есть D (именно большая), обрывается конкретно на на ней, если же что-то другое, то все ок.
Например, если параметр
XML
1
<MYID>335001D8FF5D:aa11b50fov546ov67v8455bf900</MYID>
то вытаскивается только то что до D, т.е. в данном случае 335001.
Если же его заменить на что-то другое, то все работает.
В чем может быть проблема?
0
alpap
1586 / 1237 / 403
Регистрация: 26.04.2015
Сообщений: 4,345
29.12.2016, 12:17 17
Furee,
попробуйте вместо D поставить M, Y или I и увидите что проблема шире чем вы думаете. Ваше решение не имеет право существовать, таков подход недопустим, увы.

Добавлено через 3 минуты
можете поискать мои решения на форуме по замене строки или в строке в файле xml на чистом cmd, там есть компактное рабочее решение.
1
Furee
0 / 0 / 0
Регистрация: 10.12.2016
Сообщений: 10
29.12.2016, 12:38 18
alpap,
M и Y работают, а вот I действительно тоже не хочет принимать.
Ваше решение не имеет право существовать, таков подход недопустим, увы.
А почему недопустим? Вы не могли объяснить или направить хотя бы где это объяснение можно найти?
0
alpap
1586 / 1237 / 403
Регистрация: 26.04.2015
Сообщений: 4,345
29.12.2016, 12:52 19
Furee,
потому что вы думаете что написав такую строку
Windows Batch file
1
delims=%between%
будет происходить деление на все значение переменной, ан нет, теперь каждый символ этого значения выступает в роли делителя и будет бяка. Найдите по запросу примерно "Замена в xml", "изменить в строке <...>", здесь на форуме несколько таких тем поднималось и приводились решения - ПРАВИЛЬНЫЕ, есть и мои в их числе, посмотрите какой правильный подход для решения подобных задач, потому как это еще не все проблемы с которыми вам придеться столкнуться.
0
Furee
0 / 0 / 0
Регистрация: 10.12.2016
Сообщений: 10
29.12.2016, 16:06 20
alpap,
Все! Я понял о чем Вы говорите: делитель делит все, включая и искомое значение. Чет я сразу не догадался логику включить. ))
Спасибо!
ЗЫ Тему "Внесение изменения в XML-файл" уже курю. Вторую пока не нашел.

Добавлено через 48 минут
alpap,
Скажите, а если выковыривать параметр вот типа таким способом:
Я решил все таки еще по сопротивляться своими силами ))), уж больно оно меня зацепило.
Windows Batch file
1
2
3
4
5
6
7
8
9
10
...
set "MYIDSource=C:\Source_File.xml"
set "MYIDDest=C:\Destination_File.xml"
set "between=>.*<"
 
for /f "delims=" %%a in ('type "%MYIDSource%" ^| findstr /i "MYID"') do (
  for /f "tokens=2 delims=%between%" %%b in ("%%a") do (
  echo. "%%b")
)
...
не будет конфликтов? Так эхо вроде выдает то, что надо...

Добавлено через 2 часа 15 минут
В общем очередной раз победил. ))
Вариант #3, переносит параметр ABCDEFGHIJKLMNOPQRSTUVWXYZ:1234567890:
@echo off
Windows Batch file
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
SetLocal EnableExtensions
 
set "MYIDSource=c:\Source_file.xml"
set "MYIDDest=c:\Destination_file.xml"
set "between=>.*<"
 
for /f "delims=" %%a in ('type "%MYIDSource%" ^| findstr /i "MYID"') do (
  for /f "tokens=2 delims=%between% " %%b in ("%%a") do (
    for /f "delims=" %%c in ('type "%MYIDDest%" ^| findstr /i "MYID"') do (
      for /f "tokens=2 delims=%between% " %%d in ("%%c") do (           
        for /f %%e in ('^<"%MYIDDest%" find/c /v ""') do @<"%MYIDDest%">$ (
          for /l %%f in (1 1 %%e) do @(
            set/p x=
              if defined x (cmd/v/c "if "!between: =!" equ "!between:%%d=%%d!" (echo !x:%%d=%%b!) else (echo.!x!)") else (echo.)
            set x=
            )
          )
        >nul move $ "%MYIDDest%"
      )
    )           
  )
)
 
endlocal && exit/b 0
0
29.12.2016, 16:06
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
29.12.2016, 16:06

Пакетная замена текста в файлах с передачей параметра
Добрый день. Помогите знающие разобраться со следующей задачей. В рамках...

Поиск значения параметра реестра и его замена
Приветствую, если коротко хочу батником переподключать шары. Самый простой...

Как записать в переменную значение параметра из XML-файла?
Доброго дня! Задача: Есть много xml файлов с однотипным содержимым. (Цикл по...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru