我正在寻找一个.bat脚本,该脚本运行我的XML文件并仅提取指定XML文件的某些数据。如果名称“Ian”和位置“executive”匹配,则只应提取这些XML文件的数据。如果.bat找到匹配的XML文件,它应该只提取3个指定的值。
例如:
仅提取if:
如果这些值匹配,则应提取数据:
1.currentWork
2.shortID
3.holidaycounter
我希望这不会太多工作。 XML数据都很相似。
<Name="Ian" workstampIN="2017-04-06" worknumber="XXXX" editor="XXXX" Position="Executive" currentWork="engineer" shortID="543532" holidaycounter="50" >
等
抱歉,我对.bat真的很新。感谢您的帮助!
答案 0 :(得分:0)
考虑一下:batch
是解析XML文件的不错选择。也就是说:使用适当的令牌和分隔符,使用for
循环提取数据:
@echo off
setlocal
for %%z in (*.xml) do call :extract %%z
goto :eof
:extract
for /f "tokens=1-8 delims=<> " %%a in (%*) do (
set _%%a
set _%%e
set _%%f
set _%%g
set _%%h
)
REM set _
if %_Position%=="Executive" if %_Name%=="Ian" (
echo 1. %_currentWork%
echo 2. %_shortID%
echo 3. %_holidaycounter%
) >> outputfile.txt
goto :eof
答案 1 :(得分:0)
@ECHO OFF
SETLOCAL enabledelayedexpansion
SET "sourcedir=U:\sourcedir"
SET "filename1=%sourcedir%\q43314990.txt"
SET /a filtercount=0
SET /a fieldcount=0
CALL :filterset %*
IF %filtercount%==0 GOTO syntax
IF %fieldcount%==0 GOTO syntax
FOR /f "usebackqdelims=" %%a IN ("%filename1%") DO (
SET "line=%%a"
SET "line=!line:<=!"
SET "line=!line:>=!"
SET "line=!line::==!"
CALL :filter !line!
)
GOTO :EOF
:syntax
ECHO syntax is [requiredname requiredvalue]* :: reportfieldname*
GOTO :EOF
:: set and count filters and fields
:filterset
IF "%~1"=="::" GOTO fieldset
IF "%~1"=="" GOTO :EOF
SET /a filtercount +=1
SET "$%filtercount%=%~1"
shift
SET "#%filtercount%=%~1"
shift
GOTO filterset
:fieldset
shift
IF "%~1"=="" GOTO :EOF
SET /a fieldcount +=1
SET "_%fieldcount%=%~1"
GOTO fieldset
:filter
FOR /L %%z IN (1,1,%fieldcount%) DO SET "@%%z="
SET /a matchesfound=0
:filterloop
IF "%~1"=="" GOTO report
FOR /L %%z IN (1,1,%filtercount%) DO IF /i "%~1>%~2"=="!$%%z!>!#%%z!" SET /a matchesfound+=1
FOR /L %%z IN (1,1,%fieldcount%) DO IF /i "%~1"=="!_%%z!" SET "@%%z=%~2"
SHIFT
shift
GOTO filterloop
:report
IF %matchesfound% neq %filtercount% GOTO :EOF
SET "reportline="
FOR /L %%z IN (1,1,%fieldcount%) DO SET "reportline=!reportline! !@%%z!
ECHO(%reportline:~1%
GOTO :eof
您需要更改sourcedir
的设置以适合您的具体情况。
我使用了一个名为q43314990.txt
的文件,其中包含您的数据和一些虚拟数据供我测试。
此程序可以解决您的问题。
我假设调用它的批处理命令是
thisbatch cls&amp; q43314990 name ian position executive :: currentWork shortid holidaycounter
那是(fieldname requiredvalue)根据需要重复多次&#39; ::`(reportfiledname)重复多次
和那个案子无关。
第一个操作是按call
:filterset
分析命令行。如果未同时指定过滤器和报告字段,则显示所需的语法。
否则,请将每个文件行读取到%%a
,然后读取到line
。处理line
以移除>
和<
并将:
转换为=
(如果:
应为=
,则不需要您的示例),然后调用:filter
以提取所需数据并进行报告。
:filterset
例程会查看第一个标记,并将其记录为$1
,并将相应的值记录为#1
,并继续使用$2,#2
等,直到{{找到1}}(每个名称/值对被::
命令移出(一个左边),分隔名称/值的shift
被 Space 有助于替换byy =
机制)
找到call
后,其余参数将记录为::
,_1
等 - 这些是要报告的字段名称。
_2
例程首先清除所有要报告的字段数的:filter
值。
然后,@?
提供的第一个和第二个参数与call
(之前删除的字符)连接,因此不存在,因此可用于分隔字段)并与从$ 1&gt;#1 .. $?&gt;#?构成的相同字符串进行比较在比赛中,计算比赛次数。
然后查看>
中的字段名是否与%1
中的每个必需输出字段名匹配,如果是,则将该参数的值从_?
记录到%2
然后@?
两次删除名称/值对并执行到下一个。
如果没有剩下参数,只有在找到的匹配的nuber与过滤器的数量相同时才会报告。在这种情况下,只需通过连接空格后每个选定字段的值来构建报表行。最终报告是shift
跳过第一个字符(这将是一个空格)
答案 2 :(得分:0)
给定的XML节点无效,因为它不能仅包含attributes。这是我用于测试的xml:
<root>
<N Name="Ian" workstampIN="2017-04-06" worknumber="XXXX" editor="XXXX" Position="Executive" currentWork="engineer" shortID="543532" holidaycounter="50"/>
</root>
使用xpath.bat
,您可以使用以下表达式:
call xpath.bat name.xml "//N[@Name='Ian'][@Position='Executive']/@shortID"
答案 3 :(得分:0)
当我审查这种类型的“问题”(没有OP写的代码)时,我认为他们是写作我想要的任何内容的许可;例如:
@echo off
setlocal EnableDelayedExpansion
(for /F "tokens=1,2 delims=:<>" %%a in ('findstr "Name=\"Ian\" Position=\"Executive\"" *.xml') do (
set "list=%%b"
for /F "delims=" %%c in (^"!list: ^=^
% Do NOT remove this line %
!^") do set %%c
if "!Name!+!Position!" equ ""Ian"+"Executive"" (
echo File: "%%a", currentWork=!currentWork!, shortID=!shortID!, holidaycounter=!holidaycounter!
)
)) > Outputfile.txt