批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程
[批处理文件精品]批处理版照片整理器[批处理文件精品]纯批处理备份&还原驱动在线第三方下载
返回列表 发帖

[文本处理] 【已解决】怎么用bat或vbs替换xml文件中的多部分内容?

本帖最后由 aducyl 于 2020-2-20 00:07 编辑

我想替换xml文本中的内容,但是需要满足以下条件:

1.替换多部分内容(即如果被替换的内容在xml中存在,则进行替换)
比如:
Note Bar="9" Pos="12"替换成Note Bar="9" Pos="18"
Note Bar="9" Pos="40"替换成Note Bar="9" Pos="60"
EndBar="10" EndPos="16"替换成EndBar="10" EndPos="56"
将…………(还有很多)

2.不用替换内容(即如果被替换的内容在xml中不存在,则不用进行替换)
比如:如果EndBar="16" EndPos="48"不存在,则不用进行替换
(这个部分我不希望通过列入很多个条件来达到不用替换的效果,只需要简单的语言就可以)

3.被替换和替换的文本内容中必须含有等于号、空格和半角双引号,而且转换前后不能丢失
比如:将Note Bar="9" Pos="12"替换成Note Bar="9" Pos="18",当中的等于号、半角双引号和空格在替换前后不能少。

4.最好是能够另存为一个新的xml文件,且新xml中除了需要被替换的内容变更意外,其余部分的内容不能变(即各种字符串都不能缺少、更改、丢失或删除)
  即使不能另存为新文件,那么执行后覆盖原文件的新文件当中除了需要被替换的内容变更意外,其余部分的内容不能变(即各种字符串都不能缺少、更改、丢失或删除)

5.双击做好的vbs或bat文件后,xml中除了需要被替换的内容变更意外,其余部分的内容不能变(即各种字符串都不能缺少、更改、丢失或删除)
附件: 您需要登录才可以下载或查看附件。没有帐号?注册

本帖最后由 flashercs 于 2020-2-18 20:24 编辑

editxml.bat
只要替换内容即可,不需替换的有什么用?
  1. <#*,:&cls
  2. @echo off
  3. pushd "%~dp0"
  4. powershell -NoProfile -ExecutionPolicy RemoteSigned -Command ". ([ScriptBlock]::Create((Get-Content -LiteralPath \"%~0\" -ReadCount 0 | Out-String ))) "
  5. popd
  6. pause
  7. exit /b
  8. #>
  9. # modify xml attributes
  10. # 替换内容,格式必须遵守下面样本,不要前加 Note
  11. $hashAttr = @{
  12.   'Bar="9" Pos="12"'        = 'Bar="9" Pos="18"'
  13.   'Bar="9" Pos="40"'        = 'Bar="9" Pos="60"'
  14.   'EndBar="10" EndPos="16"' = 'EndBar="10" EndPos="56"'
  15. }
  16. $xmlfile = "4.xml"
  17. $xmlfilenew = "4_new.xml"
  18. $hashValue = @{ }
  19. $re = [regex]'(\w+)="([^"]*)"'
  20. $xmldoc = New-Object -TypeName System.Xml.XmlDocument
  21. try {
  22.   $xmldoc.Load($xmlfile)
  23.   foreach ($strKey in $hashAttr.Keys) {
  24.     $strXPath = $strKey -replace '\w+=', '@$&' -replace ' @', ' and @'
  25.     $hashValue.Clear()
  26.     foreach ($reMatch in $re.Matches($hashAttr.Item($strKey))) {
  27.       $hashValue.Add($reMatch.Groups[1].Value, $reMatch.Groups[2].Value)
  28.     }
  29.     foreach ($node in $xmldoc.DocumentElement.SelectNodes(".//Note[$strXPath]")) {
  30.       foreach ($dicEntry in $hashValue.GetEnumerator()) {
  31.         $node.SetAttribute($dicEntry.Key, $dicEntry.Value)
  32.       }
  33.     }
  34.   }
  35.   $xmldoc.Save($xmlfilenew)
  36. } catch {
  37.   $_ | Out-String | Write-Host -ForegroundColor Red
  38. }
复制代码
1

评分人数

    • aducyl: 很给力,缺点是产生了多次的循环替换技术 + 1
微信:flashercs
QQ:49908356

TOP

本帖最后由 aducyl 于 2020-2-19 23:09 编辑

回复 2# flashercs


   
怎样才能按照附件BAT文件中的替换顺序对1.xml进行替换,要求:
XML文件中的每一行按照BAT文件中的顺序只进行最初的一次替换就终止(就是不要循环替换,因为有的替换内容可能会变成另一个被替换内容,)

有可能进行了多次替换,导致替换结果不对。

更确切地说是按照下面的图片来的
就是 xml文件中的每一行只进行最初的一次就不要再进行替换,保留最初的这一次替换就好

附件: 您需要登录才可以下载或查看附件。没有帐号?注册

TOP

本帖最后由 aducyl 于 2020-2-18 22:24 编辑

2楼的代码很好,再加上3楼的就更好了~~
附件: 您需要登录才可以下载或查看附件。没有帐号?注册

TOP

回复 3# aducyl
  1. <#*,:&cls
  2. @echo off
  3. pushd "%~dp0"
  4. powershell -NoProfile -ExecutionPolicy RemoteSigned -Command ". ([ScriptBlock]::Create((Get-Content -LiteralPath \"%~0\" -ReadCount 0 | Out-String ))) "
  5. popd
  6. pause
  7. exit /b
  8. #>
  9. # modify xml attributes
  10. # 替换内容,格式必须遵守下面样本,不要前加 Note
  11. $hashAttr = @{
  12.   'Bar="5" Pos="0"'        = 'Bar="5" Pos="0"'
  13.   'Bar="5" Pos="2"'        = 'Bar="5" Pos="2"'
  14.   'Bar="5" Pos="4"'        = 'Bar="5" Pos="6"'
  15.   'Bar="5" Pos="6"'        = 'Bar="5" Pos="8"'
  16.   'Bar="5" Pos="8"'        = 'Bar="5" Pos="12"'
  17.   'Bar="5" Pos="10"'       = 'Bar="5" Pos="14"'
  18.   'Bar="5" Pos="12"'       = 'Bar="5" Pos="18"'
  19.   'Bar="5" Pos="14"'       = 'Bar="5" Pos="20"'
  20.   'Bar="5" Pos="16"'       = 'Bar="5" Pos="24"'
  21.   'Bar="5" Pos="18"'       = 'Bar="5" Pos="26"'
  22.   'Bar="5" Pos="20"'       = 'Bar="5" Pos="30"'
  23.   'Bar="5" Pos="22"'       = 'Bar="5" Pos="32"'
  24.   'Bar="5" Pos="24"'       = 'Bar="5" Pos="36"'
  25.   'Bar="5" Pos="26"'       = 'Bar="5" Pos="38"'
  26.   'Bar="5" Pos="28"'       = 'Bar="5" Pos="42"'
  27.   'Bar="5" Pos="30"'       = 'Bar="5" Pos="44"'
  28.   'Bar="5" Pos="32"'       = 'Bar="5" Pos="48"'
  29.   'Bar="5" Pos="34"'       = 'Bar="5" Pos="50"'
  30.   'Bar="5" Pos="36"'       = 'Bar="5" Pos="54"'
  31.   'Bar="5" Pos="38"'       = 'Bar="5" Pos="56"'
  32.   'Bar="5" Pos="40"'       = 'Bar="5" Pos="60"'
  33.   'Bar="5" Pos="42"'       = 'Bar="5" Pos="62"'
  34.   'Bar="5" Pos="44"'       = 'Bar="6" Pos="2"'
  35.   'Bar="5" Pos="46"'       = 'Bar="6" Pos="4"'
  36.   'Bar="5" Pos="48"'       = 'Bar="6" Pos="8"'
  37.   'Bar="5" Pos="50"'       = 'Bar="6" Pos="10"'
  38.   'Bar="5" Pos="52"'       = 'Bar="6" Pos="14"'
  39.   'Bar="5" Pos="54"'       = 'Bar="6" Pos="16"'
  40.   'Bar="5" Pos="56"'       = 'Bar="6" Pos="20"'
  41.   'Bar="5" Pos="58"'       = 'Bar="6" Pos="22"'
  42.   'Bar="5" Pos="60"'       = 'Bar="6" Pos="26"'
  43.   'Bar="5" Pos="62"'       = 'Bar="6" Pos="28"'
  44.   'Bar="6" Pos="0"'        = 'Bar="6" Pos="32"'
  45.   'EndBar="5" EndPos="0"'  = 'EndBar="5" EndPos="0"'
  46.   'EndBar="5" EndPos="2"'  = 'EndBar="5" EndPos="2"'
  47.   'EndBar="5" EndPos="4"'  = 'EndBar="5" EndPos="6"'
  48.   'EndBar="5" EndPos="6"'  = 'EndBar="5" EndPos="8"'
  49.   'EndBar="5" EndPos="8"'  = 'EndBar="5" EndPos="12"'
  50.   'EndBar="5" EndPos="10"' = 'EndBar="5" EndPos="14"'
  51.   'EndBar="5" EndPos="12"' = 'EndBar="5" EndPos="18"'
  52.   'EndBar="5" EndPos="14"' = 'EndBar="5" EndPos="20"'
  53.   
  54. }
  55. $xmlfile = "1.xml"
  56. $xmlfilenew = "1_new.xml"
  57. $hashValue = @{ }
  58. $hashModified = @{ }
  59. $re = [regex]'(\w+)="([^"]*)"'
  60. $xmldoc = New-Object -TypeName System.Xml.XmlDocument
  61. try {
  62.   $xmldoc.Load($xmlfile)
  63.   foreach ($strKey in $hashAttr.Keys) {
  64.     $strXPath = $strKey -replace '\w+=', '@$&' -replace ' @', ' and @'
  65.     $strValue = $hashAttr.Item($strKey)
  66.     $hashValue.Clear()
  67.     foreach ($reMatch in $re.Matches($strValue)) {
  68.       $hashValue.Add($reMatch.Groups[1].Value, $reMatch.Groups[2].Value)
  69.     }
  70.     if (!$hashModified.ContainsKey($strValue)) {
  71.       [void]$hashModified.Add($strValue, (New-Object System.Collections.ArrayList))
  72.     }
  73.     if (!$hashModified.ContainsKey($strKey)) {
  74.       [void]$hashModified.Add($strKey, (New-Object System.Collections.ArrayList))
  75.     }
  76.     $alDst = $hashModified.Item($strValue)
  77.     $alSrc = $hashModified.Item($strKey)
  78.     foreach ($node in $xmldoc.DocumentElement.SelectNodes(".//Note[$strXPath]")) {
  79.       if (!$alSrc.Contains($node)) {
  80.         foreach ($dicEntry in $hashValue.GetEnumerator()) {
  81.           $node.SetAttribute($dicEntry.Key, $dicEntry.Value)
  82.         }
  83.         [void]$alDst.Add($node)
  84.       }
  85.     }
  86.   }
  87.   $xmldoc.Save($xmlfilenew)
  88. } catch {
  89.   $_ | Out-String | Write-Host -ForegroundColor Red
  90. }
复制代码
1

评分人数

    • aducyl: 感谢给帖子标题标注[已解决]字样技术 + 1
微信:flashercs
QQ:49908356

TOP

回复 5# flashercs


    大佬牛逼~~~~

TOP

本帖最后由 aducyl 于 2020-2-20 00:15 编辑

回复 5# flashercs


   

这是另一种xml文件,NoteInfo部分的没有问题,可以正常替换
但是图中用红色椭圆标出的部分不知为什么没有被替换掉


————————————————华丽丽的分割线————————————————


flashercs已经私下回复我了
将5楼第79行代码里的“Note”改成“*”即可。


————————————————华丽丽的分割线————————————————
附件: 您需要登录才可以下载或查看附件。没有帐号?注册

TOP

返回列表