使用文件名作为属性值(Powershell或批处理文件)搜索和替换XML属性

时间:2016-08-29 15:31:34

标签: xml loops powershell batch-file replace

我需要帮助来查找和替换属性" parentid"那有" 00000000-0000-0000-0000-000000000000"在文件夹中的每个XML文件中。没有扩展名的每个文件的实际文件名应该替换" parentid" XML中的属性。 (Powershell或批处理文件)

例如:C:\ Folder \

4de6d1b4-b014-4cb3-bb61-649737a8217b.xml
4d2345b4-b415-5656-12dv-832jnm89234n.xml
...

XML的内容:

   <comment id="4de6d1b4-b014-4cb3-bb61-649737a8217b" parentid="00000000-0000-0000-0000-000000000000" approved="True">
      <date>2014-12-20 22:23:40</date>
      <author>Joe Doe</author>
      <email>test@example.com</email>
      <country />
      <ip>0.0.0.0</ip>
      <avatar />
      <content>Test</content>
    </comment>

我感谢大家的帮助!

这是我到目前为止所用的,但它取代了整行,而不是属性的实际值。

@echo off &setlocal
setlocal enabledelayedexpansion

set "search=00000000-0000-0000-0000-000000000000"
set "replace=%%~nP"
set "textfile=%%~nxP"
set "newfile=%%~nP"
for /r %%P in (*) do (
(for /f "delims=" %%i in (%textfile%) do (
    set "line=%%i"
    set "line=!line:%search%=%replace%!"
    echo(!line!))>"%newfile%"
)
)
endlocal


@ECHO ON

2 个答案:

答案 0 :(得分:1)

在PowerShell中有很多加载/解析XML文件的例子,但在这种简单的情况下最快的解决方案就是在包含整个文件的字符串上使用纯文本搜索/替换: / p>

$searchFor = 'parentid="00000000-0000-0000-0000-000000000000"'
Get-ChildItem -Literal 'c:\folder' -Filter '*.xml' -Recurse |
    Where {
        Select-String $searchFor -Path $_ -CaseSensitive -SimpleMatch
    } |
    ForEach {
        $text = [IO.File]::ReadAllText($_.FullName)
        $text.replace($searchFor, 'parentid="' + $_.BaseName + '"') |
            Out-File (Join-Path $_.Directory "$($_.BaseName)-new.xml") -Encoding utf8
    }

答案 1 :(得分:1)

基本问题是你指的是循环范围之外的for变量,即%%P,我不建议这样做。

使用纯批处理脚本,我会将您的代码更改为:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

set "SEARCH=00000000-0000-0000-0000-000000000000"
for %%P in ("*.xml") do (
    for /F "delims=" %%I in ('
        findstr /N /R "^" "%%~P" ^& ^> "%%~fP" break
    ') do (
        set "LINE=%%I"
        setlocal EnableDelayedExpansion
        set "LINE=!LINE:*:=!"
        if defined LINE set "LINE=!LINE:%SEARCH%=%%~nP!"
        >> "%%~fP" echo(!LINE!
        endlocal
    )
)
endlocal
exit /B

这能够直接修改当前目录中的枚举*.xml文件,因此不需要临时文件来替换属性parentid

每个文件都由findstr读取,它在每行前面都有行号和冒号,以免丢失空行(请记住for /F忽略这一行)。命令行set "LINE=!LINE:*:=!"之后删除前缀。请注意,在for /F中切换延迟扩展,以免丢失文件中出现的任何惊叹号。这些措施确保原始*.xml文件内容不会被更改,当然除了替换部分。