Batch file 使用批处理脚本从xml中获取特定单词

Batch file 使用批处理脚本从xml中获取特定单词,batch-file,Batch File,我正在尝试使用sfk.exe工具从xml中提取特定单词。它所做的是提取单词所在的整个句子/行,而不仅仅是该单词。我想获取该单词并将其存储在一个临时文件中,以便以后存储在一个变量中。 这些词会改变,基本上是客户机的名称,它会根据客户机的xml而变化 sfk查找“C:\Env\Test\Test.xml”“Name”>%temp%\Test.tmp 上述代码行获取以下内容: 因此,基本上我只想得到整行,而我只想得到没有引号的“Name”。如果行布局没有改变,那么您可以尝试以下方法: 设置“Name

我正在尝试使用sfk.exe工具从xml中提取特定单词。它所做的是提取单词所在的整个句子/行,而不仅仅是该单词。我想获取该单词并将其存储在一个临时文件中,以便以后存储在一个变量中。 这些词会改变,基本上是客户机的名称,它会根据客户机的xml而变化

sfk查找“C:\Env\Test\Test.xml”“Name”>%temp%\Test.tmp

上述代码行获取以下内容:


因此,基本上我只想得到整行,而我只想得到没有引号的“Name”。

如果行布局没有改变,那么您可以尝试以下方法:

设置“Name=Microsoft”
对于/F令牌^=10^ Delims^=^“%%A(

'查找/I“%Name%”^如果行布局没有更改,则可以尝试以下操作:

设置“Name=Microsoft”
对于/F令牌^=10^ Delims^=^“%%A(

'Find/I“%Name%”^尽管批处理文件不是处理XML数据的最佳选择,因为它们不支持本地文件,但我想向您展示一种方法来完成您想要的操作:

@echo关闭
rem//捕获'find'命令的输出('sfk'命令不是必需的):
对于/F“delims=”%%L in('
^<“C:\Env\Test\Test.xml“查找/I”客户端=”
""做"(
rem//在变量中找到存储行:
设置“行=%%L”
setlocal EnableDelayedExpansion
rem/*删除第一次出现“客户端”之前的所有内容`
从字符串中删除rem;然后拆分前导“=”和训练“>”;
rem最后,从剩余字符串中删除周围的““””:*/
对于(“!行:*客户端=!”)中的/F“delims==>”%%I,请执行以下操作(
端部
rem//返回提取的字符串:
回声(%)~I
)
)

仅当在每个适用行中出现空格+
Client
,后跟一个
=
-符号时,此操作才有效。此外,此
Client=
属性必须是包含标记中的最后一个属性,因此整个属性定义
Client=“Name”
后面必须紧跟着

尽管批处理文件不是处理XML数据的最佳选择,因为它们本身不支持XML数据,但我想向您展示一种方法来完成您想要的操作:

@echo关闭
rem//捕获'find'命令的输出('sfk'命令不是必需的):
对于/F“delims=”%%L in('
^<“C:\Env\Test\Test.xml“查找/I”客户端=”
""做"(
rem//在变量中找到存储行:
设置“行=%%L”
setlocal EnableDelayedExpansion
rem/*删除第一次出现“客户端”之前的所有内容`
从字符串中删除rem;然后拆分前导“=”和训练“>”;
rem最后,从剩余字符串中删除周围的““””:*/
对于/F“delims==>”%%I in(!LINE:*Client=!)执行(
端部
rem//返回提取的字符串:
回声(%)~I
)
)

仅当在每个适用行中出现空格+
Client
,后跟一个
=
-符号时,此操作才有效。此外,此
Client=
属性必须是包含标记中的最后一个属性,因此整个属性定义
Client=“Name”
后面必须紧跟着

虽然Windows批处理可能是一种蹩脚的处理
xml
,但这个(非常简单)的情况可以通过使用一个(非常简单)脚本来解决,该脚本提供了对解析行结构的额外初步假设

但是,以下解决方案强调(尽可能)通用方法,不以包含标记内的
Client=
属性的位置、行内的唯一性(奇点)或前面的
双引号的数量等为前提:

@ECHO OFF
SETLOCAL EnableExtensions DisableDelayedExpansion
for /F "delims=" %%G in ('
      findstr /i /r "\<Client=" "D:\bat\SO\files\q44533501_input.xml"
  ') do (
    rem ECHO=merely debugging output 
        ECHO %%G
    set "_line=%%~G"
    call :lineFound
)
goto :eof

:lineFound
  rem remove cmd-poisonous characters `<` and `>` (replace them with spaces)
  set "_line=%_line:<= %"
  set "_line=%_line:>= %"

  set "_takeNextItem="
  rem parse 
  for %%g in ( %_line% ) do (
    if defined _takeNextItem (
      set "_takeNextItem="
      set "_client=%%~g"
      call :clientSet
    ) else (
      if /I "%%~g" == "Client" set "_takeNextItem=%%~g"
    )
  )
goto :eof

:clientSet
  rem ECHO=merely debugging output;
  rem      handle %_client% variable in desired manner instead 
      ECHO(%_client%
goto :eof
编辑。要解释
:lineFound
部分,让我们看一下(它主要用于处理文件,但也可以处理文本字符串):

我们要分析的
xml
行只包含上述
set
说明中提到的标准分隔符,请参见:

分隔符将一个参数与下一个参数分开-分隔符将 将命令行整理成文字

参数通常用空格分隔,但 以下也是有效的分隔符:

  • 逗号(,)
  • 分号(;)
  • 等于
  • 空格()
  • 制表符()
一些示例可能会有所帮助:
对于(%\u line%)中的%g,执行…
循环处理,逐项执行,
\u line
变量在使用标准分隔符作为项分隔符拆分后。原则上,我们获得一个序列,其中每个属性名称后面跟着属性值(但标记名称作为第一项):

请注意,
\u line
变量是硬编码的,对于这个特定的示例情况,如下所示

==> set "_line=<Org Updated="date" Database="Test" Client="Name2" Owner="Test" Version="2/1/3/4">"

==> set "_line=%_line:<= %"

==> set "_line=%_line:>= %"

==> set _line
_line= Org Updated="date" Database="Test" Client="Name2" Owner="Test" Version="2/1/3/4"
==>设置“\u行=”
==>设置“\u行=%\u行:=%”
==>设置行
_line=Org Updated=“date”Database=“Test”Client=“Name2”Owner=“Test”Version=“2/1/3/4”

尽管Windows批处理可能是一种蹩脚的处理
xml
,但这个(相当简单)的情况可以通过使用一个(相当简单)的脚本来解决,该脚本提供了关于解析行结构的额外初步假设

但是,以下解决方案强调(尽可能)通用方法,不以包含标记内的
Client=
属性的位置、行内的唯一性(奇点)或前面的
双引号的数量等为前提:

@ECHO OFF
SETLOCAL EnableExtensions DisableDelayedExpansion
for /F "delims=" %%G in ('
      findstr /i /r "\<Client=" "D:\bat\SO\files\q44533501_input.xml"
  ') do (
    rem ECHO=merely debugging output 
        ECHO %%G
    set "_line=%%~G"
    call :lineFound
)
goto :eof

:lineFound
  rem remove cmd-poisonous characters `<` and `>` (replace them with spaces)
  set "_line=%_line:<= %"
  set "_line=%_line:>= %"

  set "_takeNextItem="
  rem parse 
  for %%g in ( %_line% ) do (
    if defined _takeNextItem (
      set "_takeNextItem="
      set "_client=%%~g"
      call :clientSet
    ) else (
      if /I "%%~g" == "Client" set "_takeNextItem=%%~g"
    )
  )
goto :eof

:clientSet
  rem ECHO=merely debugging output;
  rem      handle %_client% variable in desired manner instead 
      ECHO(%_client%
goto :eof
编辑。要解释
:lineFound
部分,让我们看一下(它主要用于处理文件,但也可以处理文本字符串):

我们要解析的
xml
行只包含前面提到的标准分隔符
==> for %g in ( %_line% ) do @echo %g
Org
Updated
"date"
Database
"Test"
Client
"Name2"
Owner
"Test"
Version
"2/1/3/4"

==>
==> set "_line=<Org Updated="date" Database="Test" Client="Name2" Owner="Test" Version="2/1/3/4">"

==> set "_line=%_line:<= %"

==> set "_line=%_line:>= %"

==> set _line
_line= Org Updated="date" Database="Test" Client="Name2" Owner="Test" Version="2/1/3/4"