通过目录批量循环查找所有 XML 并将某个(未知)值替换为另一个(已知)值

Batch looping through directory find all XML and replace a certain (unknown) value with another (known) value

只是一个问题,我不知道这是否可能,但让我举例说明一下。

XML(包含几个值)

<WORKFLOW DESCRIPTION ="" ISENABLED ="YES" ISRUNNABLESERVICE ="NO" ISSERVICE ="NO" ISVALID ="YES" NAME ="DIMENSIONS" REUSABLE_SCHEDULER ="NO" SCHEDULERNAME ="Scheduler" SERVERNAME ="SERVER_NAME_DUMMY" SERVER_DOMAINNAME ="Domain_DUMMY" SUSPEND_ON_ERROR ="NO" TASKS_MUST_RUN_ON_SERVER ="NO" VERSIONNUMBER ="1">

我希望能够用 findstr 捕获(除非有更好的方法)SERVERNAME =(这在整个文档中只出现一次)并将其值替换为 SERVER_NAME_PROPER 以获得以下内容结果:

服务器名称="SERVER_NAME_PROPER".

问题是我不知道 SERVERNAME 的值,所以我不能严格搜索 SERVER_NAME_DUMMY(我也不知道长度,我看到了字符集对字符串的操作)。此外,这些行只是在它之后继续其他值和元素(没有结束行操作)。也许搜索 SERVERNAME =(promt value) 并在 SERVERDOMAIN_NAME 之前停止是明智的。因为该值在 SERVERNAME= "VALUE" 之后和 SERVERDOMAIN_NAME.

之前

我知道 SERVERNAME = 之后的值需要替换为我的硬编码值。如果我可以执行此操作,那么我可以批量创建一个 FOR 命令来循环整个目录中的所有文件并执行此特定命令。

我 2 天前在这里发布了一个替换脚本

查找字符串

"^(SERVERNAME=\x22^)^([a-z]+^)^(\x22^)"

替换为

WHATEVERYOUWANT

$1 是第一个括号,$2 第二个,$3 第三个。上面的插入符正在为 CMD 转义 - 解析后看起来像这样 (SERVERNAME=")([a-z]+)(")

无论何时使用 HTML 或 XML,最好将其解析为 HTML 或 XML,而不是试图将其抓取并破解为文本。这样,只要它是有效的标记,您就不会那么依赖格式。

为了使用 XML,您可以相当直观地将 Microsoft.XMLDOM COM 对象与 Windows 脚本宿主一起使用(或者至少希望您可以遵循我下面演示中的逻辑) .这是混合批处理 + JScript 解决方案。用 .bat 扩展名和盐来保存它。

@if (@CodeSection == @Batch) @then

@echo off
setlocal

set "attribute=SERVERNAME"
set "new_value=This works."

for %%I in (*.xml) do (
    rem // invoke JScript for each XML file
    cscript /nologo /e:JScript "%~f0" "%%~I" "%attribute%" "%new_value%"
)

rem // end main runtime
goto :EOF

@end // end batch / begin JScript chimera

var DOM = WSH.CreateObject('Microsoft.XMLDOM'),
    args = { file: WSH.Arguments(0), attr: WSH.Arguments(1), val: WSH.Arguments(2) };

DOM.load(args.file);
DOM.async = false;
DOM.setProperty('SelectionLanguage', 'XPath');

if (DOM.parseError.errorCode) {
   WSH.Echo(DOM.parseError.reason);
   WSH.Quit(1);
}

for (var d = DOM.selectNodes('//*[@' + args.attr + ']'), i = 0; i < d.length; i++)
    d[i].setAttribute(args.attr, args.val);

DOM.save(args.file);