2016-07-29 5 views
0

XMLファイルがあり、必要なタグ値を抽出し、結果をタグ名付きのcsvファイルに出力する必要があります。xmlファイルからタグ値を取得し、バッチスクリプトを使用して結果をcsvファイルに保存します。

これまでXMLタグと値を取得しようとしましたが、すべての結果が表形式のように1列に表示されます。

xmlファイルの内容(部分ファイルの内容):

<RSP> 
<HSI> 
<SN>CZ9V  </SN> 
<SP>Pro Gen8</SP> 
<UUID>C9V</UUID> 
</HSI> 
<STP>3</STP> 
<cUUID>343-11</cUUID> 
<NICS> 
<NIC> 
<PORT>1</PORT> 
<MACADDR>01:51:f2</MACADDR> 
</NIC> 
<NIC> 
<PORT>1</PORT> 
<MACADDR>00:17</MACADDR> 
</NIC> 
<NIC> 
<PORT>2</PORT> 
<MACADDR>77:28:02</MACADDR> 
</NIC> 
<NIC> 
<PORT>3</PORT> 
<MACADDR>00:04</MACADDR> 
</NIC> 
<NIC> 
<PORT>4</PORT> 
<MACADDR>00:06</MACADDR> 
</NIC> 
</NICS> 
</RSP> 

出力はoutput.csvファイルから取得しています:

SN,SP,UUID,MACADDR,cUUID 
CZ9V 
Pro Gen8 
C9V 

01:51:F2 343から11

何私は取得しようとしていた:

SN,SP,UUID,MACADDR,cUUID 
CZ9V,Pro Gen8,C9V,01:51:f2,343-11 

スプレッドシートでoutput.csvを開くと、フィルタオプションを使用して必要に応じてフィルタリングすることが簡単にできます。

コードは、これまでに取得するために午前:

echo SN,SP,UUID,MACADDR,cUUID> %outFile% 
set req_tags=SN SP UUID MACADDR cUUID 
for %%a in (%inFile%) do (
for %%c in (%req_tags%) do (
set "found=" 
set search_tag=%%c 
for /f "tokens=2 delims=>< " %%b in (' type "%%a" ^|findstr /i !search_tag! ') do set found=%%b 
if defined found >> "%outFile%" echo !found! 
) 
) 

はoutput.csvファイルにそれぞれのタグ名の下にタグvlaueを取得する必要があります。

+0

提案されている出力は、CSVとは全く異なる固定幅のテキストファイルです。 – dbenham

+0

それを得ました。私はここに期待される出力をフォーマットするべきではありません。 – HULK

答えて

0

要件が少し変わってしまったので、元のものを編集するのではなく、新しい回答を投稿することにしました。それが方法を行うかどうかは分かりませんが、ちょっと、私はベストを尽くしています... :)

XML階層を気にしないバージョンは、指定された要素のリストからトークン値を抽出するだけです。しかし、先ほど説明したように、複数の子が共通の親要素に属しているケース(XML階層には反映されていませんが)は、ではなく、がここで処理されます。しかし、出力はOPの要求に従って1行にあります。

@echo off 
setlocal enabledelayedexpansion 
set req_tags=SN SP UUID MACADDR cUUID 
set inFile="C:\tests\xmltocsv.txt" 
set outFile="C:\tests\output.csv" 
if exist %outFile% del %outFile% 

rem set the header line 
set hLine= 
for %%a in (%req_tags%) do (
    set hLine=!hLine!,%%a 
) 
call :outputlinetocsv "%hLine%" 

rem add values to file 
set csvLine= 
for %%a in (%req_tags%) do (
    set sTag=%%a 
    for /F "tokens=2 delims=<>" %%f in ('findstr /I /L "^</!sTag!" %inFile%') do (
    set line=%%f 
    set "line=!line:*>=!" 
    set csvLine=!csvLine!,!line! 
) 
) 
call :outputlinetocsv "%csvLine%" 
goto :eof 

:outputlinetocsv 
REM remove starting comma 
set myLine=%~1 
set "myLine=!myLine:*,=!" 
echo !myLine! >> %outFile% 
goto :eof 
+0

ありがとうFilipus。 2番目のコードは期待どおりに動作します。 reg_tagが入力xmlファイル内に複数回出現した場合に、コードが両方の値を取得する場合、私が見てきたことだけが発行されます。 mycaseのように、UUIDは入力ファイルに2回表示されます。 – HULK

+0

はい、これは私の投稿で説明したものです:複数の子供はこのように扱うことはできません。これらのケースを処理するために例外を記述することもできますが、絶対に汎用的にしたい場合は、前のコメントの1つで示唆したように、Scripting言語の実際のXMLパーサを使用する必要があります。 – Filipus

0

私はそれを刺しました。あなたは正しい軌道に乗っていた。以下のコードは、あなたが投稿したサンプルデータのために働いているように見え、HSI要素の中に追加する追加の項目についても動作します。

変更する必要がある唯一のものは、CSVのヘッダ行ですが、あなたは彼らが今のように、バッチファイルにパラメータとしてそれを渡すために、またはバッチファイル自体の内部の値をハードコーディングすることを選択できます。

@echo off 
setlocal enabledelayedexpansion 
set inFile="C:\tests\xmltocsv.txt" 
set outFile="C:\tests\output.csv" 
if exist %outFile% del %outFile% 
set csvline= 
echo SN SP UUID > %outFile% 
(for /F "delims=" %%a in ('findstr /I /L /V "^<HSI" %inFile%') do (
    if "%%a" EQU "</HSI>" (
    echo !csvline! & set csvline= 
) ELSE (
    set line=%%a & set "line=!line:*>=!" & for /F "delims=<" %%b in ("!line!") do (IF "%%b" NEQ " " (IF "!csvline!" NEQ "" (set csvline=!csvline! %%b) ELSE (set csvline=%%b))) 
) 
)) >> %outFile% 
+0

Filipusありがとうございますが、あなたのコードを実行すると、output.csvファイルに値がありませんでした。また、入力ファイルにはタグがあり、必要なタグ/値は別の親タグの下にあります(のタグだけではありません)ので、私はex:requried_tags = "SN SP UUID .. ... etc "というコードで、これらのタグ値を取得し、結果がoutput.csvに取得され、タグ名を持つ最初の行が対応する値以下になるようにします。申し訳ありませんが、適切なinput.xmlファイルの内容を一部だけでなく与えておくべきです。 (私はそれを今更新しました) – HULK

+0

OK、コードでいくつかの変更を加えましたので、requried_tagを検索してoutput.csvに値を送ることができます。それは機能していますが、すべてのタグ値が最初の列の1つの列の次に次々になっています。私は今何をする必要があるか分からない。ビットはどんな助け/示唆も歓迎しました。私は初期コード/出力を更新しました。 – HULK

+0

同じ親の下に格納されていないタグがどのアイテムに属しているかをどのように知ることができるか分かりません。あなたの例では、/ NICS/NIC要素の下にある項目をHSI要素の下の項目と照合していることが示されていますが、おそらくいくつかのNIC要素を持つ可能性があります。入力ファイルに複数のHSI要素のインスタンスがありますか?彼らはHSISの親の下にグループ化されていますか? – Filipus

関連する問題