标题: [文本处理] 【已解决】怎么用bat或vbs替换xml文件中的多部分内容? [打印本页]
作者: aducyl 时间: 2020-2-18 14:34 标题: 【已解决】怎么用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:23
本帖最后由 flashercs 于 2020-2-18 20:24 编辑
editxml.bat
只要替换内容即可,不需替换的有什么用?- <#*,:&cls
- @echo off
- pushd "%~dp0"
- powershell -NoProfile -ExecutionPolicy RemoteSigned -Command ". ([ScriptBlock]::Create((Get-Content -LiteralPath \"%~0\" -ReadCount 0 | Out-String ))) "
- popd
- pause
- exit /b
- #>
- # modify xml attributes
- # 替换内容,格式必须遵守下面样本,不要前加 Note
- $hashAttr = @{
- 'Bar="9" Pos="12"' = 'Bar="9" Pos="18"'
- 'Bar="9" Pos="40"' = 'Bar="9" Pos="60"'
- 'EndBar="10" EndPos="16"' = 'EndBar="10" EndPos="56"'
- }
- $xmlfile = "4.xml"
- $xmlfilenew = "4_new.xml"
-
- $hashValue = @{ }
- $re = [regex]'(\w+)="([^"]*)"'
- $xmldoc = New-Object -TypeName System.Xml.XmlDocument
- try {
- $xmldoc.Load($xmlfile)
- foreach ($strKey in $hashAttr.Keys) {
- $strXPath = $strKey -replace '\w+=', '@$&' -replace ' @', ' and @'
- $hashValue.Clear()
- foreach ($reMatch in $re.Matches($hashAttr.Item($strKey))) {
- $hashValue.Add($reMatch.Groups[1].Value, $reMatch.Groups[2].Value)
- }
- foreach ($node in $xmldoc.DocumentElement.SelectNodes(".//Note[$strXPath]")) {
- foreach ($dicEntry in $hashValue.GetEnumerator()) {
- $node.SetAttribute($dicEntry.Key, $dicEntry.Value)
- }
- }
- }
- $xmldoc.Save($xmlfilenew)
- } catch {
- $_ | Out-String | Write-Host -ForegroundColor Red
- }
复制代码
作者: aducyl 时间: 2020-2-18 21:37
回复 2# flashercs
怎样才能按照附件BAT文件中的替换顺序对1.xml进行替换,要求:
XML文件中的每一行按照BAT文件中的顺序只进行最初的一次替换就终止(就是不要循环替换,因为有的替换内容可能会变成另一个被替换内容,)
有可能进行了多次替换,导致替换结果不对。
更确切地说是按照下面的图片来的
就是 xml文件中的每一行只进行最初的一次就不要再进行替换,保留最初的这一次替换就好
作者: aducyl 时间: 2020-2-18 22:10
本帖最后由 aducyl 于 2020-2-18 22:24 编辑
2楼的代码很好,再加上3楼的就更好了~~
作者: flashercs 时间: 2020-2-19 10:24
回复 3# aducyl - <#*,:&cls
- @echo off
- pushd "%~dp0"
- powershell -NoProfile -ExecutionPolicy RemoteSigned -Command ". ([ScriptBlock]::Create((Get-Content -LiteralPath \"%~0\" -ReadCount 0 | Out-String ))) "
- popd
- pause
- exit /b
- #>
- # modify xml attributes
- # 替换内容,格式必须遵守下面样本,不要前加 Note
- $hashAttr = @{
- 'Bar="5" Pos="0"' = 'Bar="5" Pos="0"'
- 'Bar="5" Pos="2"' = 'Bar="5" Pos="2"'
- 'Bar="5" Pos="4"' = 'Bar="5" Pos="6"'
- 'Bar="5" Pos="6"' = 'Bar="5" Pos="8"'
- 'Bar="5" Pos="8"' = 'Bar="5" Pos="12"'
- 'Bar="5" Pos="10"' = 'Bar="5" Pos="14"'
- 'Bar="5" Pos="12"' = 'Bar="5" Pos="18"'
- 'Bar="5" Pos="14"' = 'Bar="5" Pos="20"'
- 'Bar="5" Pos="16"' = 'Bar="5" Pos="24"'
- 'Bar="5" Pos="18"' = 'Bar="5" Pos="26"'
- 'Bar="5" Pos="20"' = 'Bar="5" Pos="30"'
- 'Bar="5" Pos="22"' = 'Bar="5" Pos="32"'
- 'Bar="5" Pos="24"' = 'Bar="5" Pos="36"'
- 'Bar="5" Pos="26"' = 'Bar="5" Pos="38"'
- 'Bar="5" Pos="28"' = 'Bar="5" Pos="42"'
- 'Bar="5" Pos="30"' = 'Bar="5" Pos="44"'
- 'Bar="5" Pos="32"' = 'Bar="5" Pos="48"'
- 'Bar="5" Pos="34"' = 'Bar="5" Pos="50"'
- 'Bar="5" Pos="36"' = 'Bar="5" Pos="54"'
- 'Bar="5" Pos="38"' = 'Bar="5" Pos="56"'
- 'Bar="5" Pos="40"' = 'Bar="5" Pos="60"'
- 'Bar="5" Pos="42"' = 'Bar="5" Pos="62"'
- 'Bar="5" Pos="44"' = 'Bar="6" Pos="2"'
- 'Bar="5" Pos="46"' = 'Bar="6" Pos="4"'
- 'Bar="5" Pos="48"' = 'Bar="6" Pos="8"'
- 'Bar="5" Pos="50"' = 'Bar="6" Pos="10"'
- 'Bar="5" Pos="52"' = 'Bar="6" Pos="14"'
- 'Bar="5" Pos="54"' = 'Bar="6" Pos="16"'
- 'Bar="5" Pos="56"' = 'Bar="6" Pos="20"'
- 'Bar="5" Pos="58"' = 'Bar="6" Pos="22"'
- 'Bar="5" Pos="60"' = 'Bar="6" Pos="26"'
- 'Bar="5" Pos="62"' = 'Bar="6" Pos="28"'
- 'Bar="6" Pos="0"' = 'Bar="6" Pos="32"'
- 'EndBar="5" EndPos="0"' = 'EndBar="5" EndPos="0"'
- 'EndBar="5" EndPos="2"' = 'EndBar="5" EndPos="2"'
- 'EndBar="5" EndPos="4"' = 'EndBar="5" EndPos="6"'
- 'EndBar="5" EndPos="6"' = 'EndBar="5" EndPos="8"'
- 'EndBar="5" EndPos="8"' = 'EndBar="5" EndPos="12"'
- 'EndBar="5" EndPos="10"' = 'EndBar="5" EndPos="14"'
- 'EndBar="5" EndPos="12"' = 'EndBar="5" EndPos="18"'
- 'EndBar="5" EndPos="14"' = 'EndBar="5" EndPos="20"'
-
- }
- $xmlfile = "1.xml"
- $xmlfilenew = "1_new.xml"
-
- $hashValue = @{ }
- $hashModified = @{ }
- $re = [regex]'(\w+)="([^"]*)"'
- $xmldoc = New-Object -TypeName System.Xml.XmlDocument
- try {
- $xmldoc.Load($xmlfile)
- foreach ($strKey in $hashAttr.Keys) {
- $strXPath = $strKey -replace '\w+=', '@$&' -replace ' @', ' and @'
- $strValue = $hashAttr.Item($strKey)
- $hashValue.Clear()
- foreach ($reMatch in $re.Matches($strValue)) {
- $hashValue.Add($reMatch.Groups[1].Value, $reMatch.Groups[2].Value)
- }
- if (!$hashModified.ContainsKey($strValue)) {
- [void]$hashModified.Add($strValue, (New-Object System.Collections.ArrayList))
- }
- if (!$hashModified.ContainsKey($strKey)) {
- [void]$hashModified.Add($strKey, (New-Object System.Collections.ArrayList))
- }
- $alDst = $hashModified.Item($strValue)
- $alSrc = $hashModified.Item($strKey)
- foreach ($node in $xmldoc.DocumentElement.SelectNodes(".//Note[$strXPath]")) {
- if (!$alSrc.Contains($node)) {
- foreach ($dicEntry in $hashValue.GetEnumerator()) {
- $node.SetAttribute($dicEntry.Key, $dicEntry.Value)
- }
- [void]$alDst.Add($node)
- }
- }
- }
- $xmldoc.Save($xmlfilenew)
- } catch {
- $_ | Out-String | Write-Host -ForegroundColor Red
- }
复制代码
作者: aducyl 时间: 2020-2-19 11:04
回复 5# flashercs
大佬牛逼~~~~
作者: aducyl 时间: 2020-2-19 22:23
回复 5# flashercs
这是另一种xml文件,NoteInfo部分的没有问题,可以正常替换
但是图中用红色椭圆标出的部分不知为什么没有被替换掉
————————————————华丽丽的分割线————————————————
flashercs已经私下回复我了
将5楼第79行代码里的“Note”改成“*”即可。
————————————————华丽丽的分割线————————————————
欢迎光临 批处理之家 (http://www.bathome.net/) |
Powered by Discuz! 7.2 |