2014-11-03 3 views
0

XML 파일 (file_1.xml 및 file_2.xml)을 읽고 태그 사이의 문자열을 추출하여 TXT 파일에 기록하는 코드를 작성했습니다. 의DOS 배치 : XML 파일의 큰 따옴표 다루기

<AAA>C086002-T1111</AAA> 
<AAA>C086002-T1222 </AAA> 
<AAA>C086002-TR333 "</AAA> 
<AAA>C086002-T5444 </AAA> 

내용 :이 문제는 일부 문자열은 큰 따옴표를 포함하고 프로그램이 다음 ... 적절한 지침을 (문자열의 일부)로서 file_1.xml의

내용을 이러한 문자를 취한다는 것입니다 file_2.xml :

<AAA>C086002-T5555 </AAA> 
<AAA>C086002-T1666</AAA> 
<AAA>C086002-T1777 "</AAA> 
<AAA>C086002-T1888   "</AAA> 

내 코드 :

@echo off 

setlocal enabledelayedexpansion 

for /f "delims=;" %%f in ('dir /b D:\depart\*.xml') do (

    for /f "usebackq delims=;" %%z in ("D:\depart\%%f") do (

     (for /f "delims=<AAA></AAA> tokens=2" %%a in ('echo "%%z" ^| Findstr /r "<AAA>"') do (

      set code=%%a 
      set code=!code:""=! 
      set code=!code: =! 
      echo !code! 

     )) >> result.txt 
    ) 
) 

내가 t를 얻을 수 그의 결과. 문자 :

C086002-T1111 
C086002-T1222 
C086002-T5444 
C086002-T5555 
C086002-T1666 

사실 8 줄 중 3 줄이 누락되었습니다. 이 줄에는 큰 따옴표 나 큰 따옴표가 포함 된 줄을 포함합니다 ...

어떻게 이러한 문자를 처리하여 문자열의 일부로 간주 할 수 있습니까?

+0

아야. 왜 아래 표를 던지겠습니까? 좋은 코드가 아닐 수도 있습니다. XML을 구문 분석하기 위해 일괄 처리를 사용하지 않아야한다고 주장 할 수 있습니다. 그러나 질문은 잘 생각되어 보였고 합리적으로 잘 설명되었습니다. OP는 분명히 자조에 시간을 들였고 문제를 진단 할 수 있었지만 해결책을 찾지 못했습니다. 나에게 좋은 질문 인 것 같다. – dbenham

+0

@dbenham : http://stackoverflow.com/questions/26676043/dos-batch-append-xml-tags-in-unique-txt-file – Magoo

답변

2

XML은 일반적으로 공백을 무시하기 때문에 일괄 처리로 XML을 파싱하는 것은 위험한 사업입니다. XML을 또 다른 유효한 형식으로 다시 포맷하기 만하면 스크립트를 작성할 수 있습니다. 즉

나는 완전히 관찰 된 행동을 설명하기를 통해 문제를 추적하지 않은 ... 말했다되고 있지만, 불균형 견적이 라인에 문제의 원인이되는 :

(for /f "delims=<AAA></AAA> tokens=2" %%a in ('echo "%%z" ^| Findstr /r "<AAA>"') do (

당신은 것을 제거 할 수 있습니다 문제를 해결하고 사전에 인용 부호를 제거하여 작업을 분류하도록 코드를 작성하십시오.

@echo off 

setlocal enabledelayedexpansion 
del result.txt 
for /f "delims=;" %%f in ('dir /b D:\depart\*.xml') do (
    for /f "usebackq delims=;" %%z in ("D:\depart\%%f") do (
    set code=%%z 
    set code=!code:"=! 
    set code=!code: =! 
    (for /f "delims=<AAA></AAA> tokens=2" %%a in ('echo "!code!" ^| Findstr /r "<AAA>"') do (
     echo %%a 
    )) >> result.txt 
) 
) 

그러나 잠재적 인 주요 문제가 있습니다. DELIMS는 문자열을 지정하지 않습니다. 문자 목록을 지정합니다. 따라서 DELIMS=<AAA></AAA>DELIMS=<>/A과 같습니다. 요소 값에 A 또는 /가 있으면 코드가 실패합니다. 당신은 어떤 루프없이 한 번에 모든 파일에서 모든 <AAA>----</AAA> 라인을 수집하는 FINDSTR을 사용할 수 있습니다

먼저 해제 :

findstr /r "<AAA>.*</AAA>" "D:\depart\*.xml" 

각 일치하는 줄 것이다 훨씬 더 좋은 방법이 있습니다

마찬가지로 매칭 라인 다음에 콜론 파일 경로로 출력 될,, 상기 파일 경로를 포함없다

D:\depart\file_1.xml:<AAA>C086002-T1111</AAA> 

for /f "delims=<> tokens=3" %%A in (... 

마지막으로, 전체 루프 괄호를 넣을 수 있습니다, 그냥 한 번 재 : 10 또는 >은, 그래서 당신은 결과를 반복하는 다음과 같은 적절한 토큰을 캡처 할 수 있습니다. 각 실행마다 새 파일을 만들길 원하기 때문에 > 대신 >>을 사용합니다.

앞이나 뒤의 공백/따옴표 만 다듬어 야한다고 가정하면 솔루션이 훨씬 간단합니다. 따옴표를 DELIM 문자로 지정하려면 이상한 구문이 필요합니다. 마지막 ^%%B 사이에는 공백이 두 개 있습니다. 이스케이프 된 첫 번째 공간은 DELIM 문자로 간주됩니다. 이스케이프 처리되지 않은 공간은 FOR/F 옵션 문자열을 종료합니다. 응답

@echo off 
>result.txt (
    for /f "delims=<> tokens=3" %%A in (
    'findstr /r "<AAA>.*</AAA>" "D:\depart\*.xml"' 
) do for /f delims^=^"^ %%B in ("%%A") do echo(%%B 
) 

UPDATE 내가 데이터 값은 콜론을 포함하지 않습니다 있으리라 믿고있어

언급합니다.

각 출력 행에 소스 파일 이름을 추가하려면 첫 번째 토큰 (소스 파일)과 세 번째 토큰 (데이터 값)을 캡처하기 위해 첫 번째 FOR/F를 변경하기 만하면됩니다. . 파일에는 전체 경로와 후행 콜론이 포함됩니다. 두 번째 FOR/F는 ~nx 수정자를 사용하여 원본 데이터 문자열에 파일을 추가하여 이름과 확장명 (드라이브 또는 경로 없음) 만 가져오고 콜론이 DELIMS 옵션에 추가되어 후행 콜론이 잘립니다.

@echo off 
>result.txt (
    for /f "delims=<> tokens=1,3" %%A in (
    'findstr /r "<AAA>.*</AAA>" "D:\depart\*.xml"' 
) do for /f delims^=:^"^ %%C in ("%%B;%%~nxA") do echo %%C 
) 
+0

대단히 감사합니다 @dbenham! 당신의 코드는 꽤 훌륭하고 간결 해 보인다. 나는 단지'echo (%% B)'다음에 파싱 된 각 XML 파일의 이름을 반향시켜야 할 것이다. 코드에 어떻게 포함시킬 수 있습니까? result.txt의 내용 예 :'C086002-T346; 86002_2014_1.xml'. 조언 해 주셔서 감사합니다! – wiltomap

+0

@wiltomap - 업데이트 된 답변보기 – dbenham

0

파일 이름 에코 나는 @dbenham 제안을 유지하고 내가 순서를 완료하면이 코드에 대한 당신의 의견에 대한

@echo off 
>result.txt (
    for /f %%f in ("D:\depart\*.xml") do (
     for /f "delims=<> tokens=3" %%A in ('findstr /r "<AAA>.*</AAA>" "D:\depart\*.xml"') do (
      for /f delims^=^"^ %%B in ("%%A") do (
       echo %%B;%%f 
      ) 
     ) 
    ) 
) 

감사합니다!

+0

아니요, 작동하지 않습니다. 모든 파일을 반복하고 각 개별 파일에 대해 FINDSTR을 호출하거나 FINDSTR이 모든 파일을 한 번에 검색하도록 할 수 있습니다. 그러나 모든 파일을 반복하지 말고 반복적으로 FINDSTR이 모든 파일을 검색하도록해야합니다. – dbenham

+0

확인. 그렇다면 어떻게 파일 이름을 마지막 echo에서 얻을 수 있습니까? 나는 해결책을 찾고 있는데 지금은 찾을 수 없다 ... – wiltomap

+0

'findstr' 내부의'D : \ depart \ *. xml'을'%% f '로 대체하는 것에 대해 어떻게 생각하십니까? 이것은 더 논리적이어야합니다 ... – wiltomap