基于SubNode Value删除XML中的节点

时间:2014-01-16 17:57:51

标签: xml batch-file

目前,我有script执行以下操作:

  1. 查找特定文件夹
  2. 解压缩所有* .zip文件
  3. 读取包含四列(oldid,oldname,newid,newname)的特定CSV file
  4. 在文件夹(sample.xml
  5. 中递归查找所有* .xml文件
  6. 循环浏览* .xml文件,创建副本(原始bak&潜在修改bak)
  7. 用newid,newname替换oldid,oldname
  8. 如果已修改,则写入XML,删除原始文件,将bak移动到原始文件。
  9. 我的问题是这个。对于没有替换的项目(例如line 3 of csv),我需要删除整个节点。

    所以在我的XML中,我有这个:

    <choice id="8" isActive="yes">
        <name><![CDATA[<font color='#0000FF' ><u>Mentoring Tools</u> </font>]]></name>
        <url><![CDATA[http://olc.inside.domain.com/olc/apps/pro/DeepLinking/LoadAsset.cfm?coursename=mgmt_10_a03_bs_enus]]></url>
    </choice>
    

    当我走过这个时,我会在current loop中逐行触摸它们。所以我的问题是,有没有办法设置一个分隔符来读取以替换字符串或删除所述节点?或者,由于替换工作,使用替换工具写一个空行?

    所以,

    <choice id="8" isActive="yes">
        <name><![CDATA[<font color='#0000FF' ><u>Mentoring Tools</u> </font>]]></name>
        <url><![CDATA[http://olc.inside.domain.com/olc/apps/pro/DeepLinking/LoadAsset.cfm?coursename=mgmt_10_a03_bs_enus]]></url>
    </choice>
    

    变为

    <choice id="8" isActive="yes">
    </choice>
    

    如果这样可行,那么使用另一个批处理删除任何空<choice>个节点?

    顺便提一下,为什么这会改变>> "%BAKFILE%" echo.!LINE! =&gt; if not "%~3"=="" >> "%BAKFILE%" echo.!LINE!不起作用?

    Related Question #21153875

2 个答案:

答案 0 :(得分:0)

对不起。你的问题很烦人。首先,您提供的信息太多与问题无关。但是,当你描述你的问题时,你不够清楚:“有没有办法设置一个分隔符来读取以替换字符串或删除所述节点?”。

如果这是相关循环:

REM Walk through XML Lines
for /F "delims=" %%U in (%~1) do (
    set LINE=%%U
    setlocal enabledelayedexpansion

    if not "!LINE!" == "!LINE:%~2=!" (
        set LINE=!LINE:%~2=%~3!
        set modified=!string:%~2=%~3!

    )
    >> "%BAKFILE%" echo.!LINE!
    endlocal
)

...这是输入数据:

<choice id="8" isActive="yes">
    <name><![CDATA[<font color='#0000FF' ><u>Mentoring Tools</u> </font>]]></name>
    <url><![CDATA[http://olc.inside.domain.com/olc/apps/pro/DeepLinking/LoadAsset.cfm?coursename=mgmt_10_a03_bs_enus]]></url>
</choice>

...然后我不明白输出在哪种情况下(或者应该是,或者你想成为):

<choice id="8" isActive="yes">
</choice>

无论如何,我仍然不明白这些东西是如何与你的真正的问题相关的。

如果您真正的问题是:“如何取消整个空<choice...> </choice>节点的输出...”,那么我建议您以非常清晰的方式完成“...”部分我们知道要解决的问题是什么。

答案 1 :(得分:0)

@ECHO OFF
SETLOCAL
for /f "tokens=1-4 delims=," %%a in (courses.csv) do (
set "_oID=%%a"
set "_oName=%%b"
set "nID=%%c"
set "nName=%%d"
call :newprocessLine
PAUSE
)
GOTO :eof

:newprocessLine
:: Simulate xml-file-located-by-for/r
SET "sourcefile=q21169335.txt"
SET "destfile=q21169335.txt.new"
DEL %destfile% 2>nul

CALL :zap $
SET "choicenode="
FOR /f "delims=" %%a IN (%sourcefile%) DO (
 SET "line=%%a"
 REM line below delims=redirectors TAB space
 FOR /f "delims=<>   " %%t IN ("%%a") DO SET "tag=%%t"
 CALL :rep
)

FC %sourcefile% %destfile%

GOTO :eof

:: with each line, buffer if in choice node else output
:rep
IF "%tag%"=="choice" SET choicenode=Y&SET "targetnode="
IF DEFINED choicenode (CALL :buffer) ELSE (CALL :out line)
IF "%tag%"=="/choice" GOTO eciohctag
GOTO :eof

:: save and flag whether target
:buffer
SET /a count$+=1
SET "$%count$%=%line%"
CALL SET "newline=%%line:%_oID%=%%"
IF NOT "%line%"=="%newline%" SET targetnode=Y
GOTO :eof

:: Process any changes required
:: If no new ID and no new Name, eliminate node
:eciohctag
IF NOT DEFINED targetnode GOTO putbuffer
IF NOT DEFINED nID IF NOT DEFINED nName GOTO noput
FOR /l %%z IN (1,1,%count$%) DO (
 CALL SET "$%%z=%%$%%z:%_oID%=%nID%%%"
 CALL SET "$%%z=%%$%%z:%_oName%=%nName%%%"
)
:putbuffer
FOR /l %%z IN (1,1,%count$%) DO (CALL :out $%%z)

:noput
CALL :zap $
SET "choicenode="
GOTO :eof

:: remove all envvars starting %1
:zap
FOR /f "delims==" %%z IN ('set %1 2^>nul') DO SET "%%z="
SET /a count%1=0
GOTO :eof

:out
FOR /f "tokens=1*delims==" %%x IN ('set %1') DO >>%destfile% ECHO(%%y
GOTO :eof

我建议您整理文件复制/备份生成方案。在我看来你正在复制文件并立即删除它们......

考虑到这一点,我已经生成了这个版本。从本质上讲,它处理相同的文件q21169335.txt.XML示例的副本)并生成新文件q21169335.txt.new三次,在FC之后停止以显示差异。对于courses.csv的每一行,三次都是一次,以显示每次迭代所做的各个更改。

本质上,方法是检测标记,缓冲choice/choice之间的任何行,如果缓冲的节点包含old-id字符串,则处理该节点,用新的替换旧数据。

如果新数据既没有新名称也没有新ID,则跳过该节点。


针对发布到github的文件中的数据运行的结果:

Comparing files q21169335.xml and Q21169335.XML.NEW
***** q21169335.xml
<choice id="9" isActive="yes">
<name><![CDATA[<font color='#0000FF' ><u>Mentoring Effectively</u> </font>]]></name>
<url><![CDATA[http://olc.inside.domain.com/olc/apps/pro/DeepLinking/LoadAsset.cfm?coursename=mgmt_10_a01_bs_enus]]></url>
</choice>
***** Q21169335.XML.NEW
<choice id="9" isActive="yes">
<name><![CDATA[<font color='#0000FF' ><u>Essential Mentoring Techniques</u> </font>]]></name>
<url><![CDATA[http://olc.inside.domain.com/olc/apps/pro/DeepLinking/LoadAsset.cfm?coursename=mgmt_39_a01_bs_enus]]></url>
</choice>
*****

Press any key to continue . . . 
Comparing files q21169335.xml and Q21169335.XML.NEW
***** q21169335.xml
<choice id="7" isActive="yes">
<name><![CDATA[<font color='#0000FF' ><u>Mentoring as a Manager</u> </font>]]></name>
<url><![CDATA[http://olc.inside.domain.com/olc/apps/pro/DeepLinking/LoadAsset.cfm?coursename=mgmt_10_a02_bs_enus]]></url>
</choice>
***** Q21169335.XML.NEW
<choice id="7" isActive="yes">
<name><![CDATA[<font color='#0000FF' ><u>Essential Mentoring Techniques</u> </font>]]></name>
<url><![CDATA[http://olc.inside.domain.com/olc/apps/pro/DeepLinking/LoadAsset.cfm?coursename=mgmt_39_a02_bs_enus]]></url>
</choice>
*****

Press any key to continue . . . 
Comparing files q21169335.xml and Q21169335.XML.NEW
***** q21169335.xml
</choice>
<choice id="8" isActive="yes">
<name><![CDATA[<font color='#0000FF' ><u>Mentoring Tools</u> </font>]]></name>
<url><![CDATA[http://olc.inside.domain.com/olc/apps/pro/DeepLinking/LoadAsset.cfm?coursename=mgmt_10_a03_bs_enus]]></url>
</choice>
<choice id="9" isActive="yes">
***** Q21169335.XML.NEW
</choice>
<choice id="9" isActive="yes">
*****

Press any key to continue . . . 

以什么方式失败?