0

XML ファイルがあり、抽出する必要があります

testname

のすべてのインスタンスから

<con:testSuite name="testname" 

XML ファイル内。

これにアプローチする方法、またはこれがバッチで可能かどうかはよくわかりません。

これが私がこれまでに考えたことです:

1) FINDSTR を使用して、

<con:testSuite name=

次のように、変数または一時ファイルで:

FINDSTR /C:"<con:testSuite name=" file.xml > tests.txt

2) どういうわけかそのファイルまたは変数を使用して文字列を抽出します

同じ行に一致する文字列のインスタンスが複数ある場合があることに注意してください。

私はバッチの初心者であり、助けていただければ幸いです。

4

1 に答える 1

3

XML の解析は、バッチでは非常に苦痛です。Batch は、そもそも適切なテキスト プロセッサではありません。ただし、ある程度の努力をすれば、通常は特定の XML ファイルから必要なデータを抽出できます。しかし、入力ファイルは、パーサーを破壊する同等の有効な XML 形式に簡単に再配置される可能性があります。

その免責事項を邪魔にならないように...

これがネイティブバッチソリューションです

@echo off
setlocal disableDelayedExpansion
set input="test.xml"
set output="names.txt"

if exist %output% del %output%
for /f "delims=" %%A in ('findstr /n /c:"<con:testSuite name=" %input%') do (
  set "ln=%%A"
  setlocal enableDelayedExpansion
  call :parseLine
  endlocal
)
type %output%
exit /b

:parseLine
set "ln2=!ln:*<con:testSuite name=!"
if "!ln2!"=="!ln!" exit /b
for /f tokens^=2^ delims^=^" %%B in ("!ln2!") do (
  setlocal disableDelayedExpansion
  >>%output% echo(%%B
  endlocal
)
set "ln=!ln2!"
goto :parseLine

FINDSTRオプションは、厄介なデフォルトの FOR "EOL" オプションについて心配する必要がないように/N、a で始まる行がないことを保証するためだけに存在します。;

遅延展開のオンとオフの切り替えは!、入力ファイルに含まれる可能性のある文字を保護するためです。が入力に表示されないことがわかっている場合は!、単に上部にある他のコマンドとコマンドsetlocal enableDelayedExpansionをすべて削除できます。setlocalendlocal

最後の FOR /F は、特別なエスケープ シーケンスを使用して、二重引用符を DELIM 文字として指定できるようにします。

コメントの追加質問への回答

一致する行全体が返されるため、既存の FINDSTR コマンドに追加の制約を単純に追加することはできません。「同じ行に一致する文字列のインスタンスが複数ある可能性がある」と自分で言ったことを思い出してください。最初の名前は正しいプレフィックスで始まる場合があり、同じ行の 2 番目の名前はそうでない場合があります。適切に開始するものだけを保持する必要があります。

echo(%%B >>%output%1 つの解決策は、次のように単純に行を変更することです。

echo(%%B|findstr "^lp_" >>%output%

FINDSTR は、正規表現のメタ文字を使用し^て、文字列が で始まる必要があることを指定していますlp_。引用符はこの時点で既に削除されているため、心配する必要はありません。

ただし、将来、"検索文字列に含めなければならない状況に遭遇する可能性があります。lp_さらに、不必要に呼び出されないように、最初の FINDSTR に画面を含める方がわずかに高速になる場合があります:parseLine

FINDSTR では、検索文字列の二重引用符をバック スラッシュでエスケープする必要があります。ただし、Windows CMD プロセッサにも独自のエスケープ規則があります。のような特殊文字は>、引用符で囲むかエスケープする必要があります。元のコードでは引用符を使用していましたが、文字列に引用符を含める必要があるため、コマンドで引用符が不均衡になります。Windows バッチは通常、ペアの引用符が好きです。CMD の場合、少なくとも 1 つの引用符を としてエスケープする必要があります^"。CMD と FINDSTR の両方で引用符をエスケープする必要がある場合は、次のようになり\^"ます。

ただし、CMD の観点から機能的に引用されなくなった文字列内の特殊文字は、^同様にエスケープする必要があります。

すべての特殊文字をエスケープする 1 つのソリューションを次に示します。それはひどく見え、非常に混乱しています。

for /f "delims=" %%A in ('findstr /n /c:^"^<con:testSuite^ name^=\^"lp_^" %input%') do (

はるかに優れた別のソリューションを次に示しますが、CMD でエスケープされたものと FINDSTR でエスケープされたものを追跡するのは依然として混乱を招きます。

for /f "delims=" %%A in ('findstr /n /c:"<con:testSuite name=\"lp_^" %input%') do (

物事を少し単純にする 1 つの方法は、検索を正規表現に変換することです。を使用して、単一の二重引用符を検索できます[\"\"]。これは、引用符または引用符のいずれかに一致する文字クラス式です。ばかげています。ただし、CMDが満足できるように、引用符をペアに保ちます。これで、CMD の文字をエスケープすることを心配する必要がなくなり、正規表現検索文字列に集中できます。

for /f "delims=" %%A in ('findstr /nr /c:"<con:testSuite name=[\"\"]lp_" %input%') do (
于 2012-06-21T16:33:42.507 に答える