Reputation: 35
I am trying to write a simple Windows batch (.cmd
) script that copies some XML element from one XML file and insert it in the right place in another file.
The first XML file has a structure like this:
<config>
<jx></jx>
<roul>
<rect>
</rect>
<background>
</background>
<text>R</text>
<color>123</color>
<vcenter>true</vcenter>
<textformat>center</textformat>
<rl>
<r1>
<egmid>G</egmid>
<number>1</number>
</r1>
<r2>
<egmid>C</egmid>
<number>2</number>
</r2>
</rl>
</roul>
<a></a>
<b><b>
</config>
the second (destination) xml file before the merge:
<config>
<jx></jx>
<roul>
<rect>
</rect>
<background>
</background>
<text>R</text>
<color>123</color>
<vcenter>true</vcenter>
<textformat>center</textformat>
<rl> </rl>
</roul>
<a></a>
<b><b>
</config>
An after the merge it should look similar to the source xml file:
<config>
<jx></jx>
<roul>
<rect>
</rect>
<background>
</background>
<text>R</text>
<color>123</color>
<vcenter>true</vcenter>
<textformat>center</textformat>
<rl>
<r1>
<egmid>G</egmid>
<number>1</number>
</r1>
<r2>
<egmid>C</egmid>
<number>2</number>
</r2>
</rl>
</roul>
<a></a>
<b><b>
</config>
I need to copy all the tags that are between the <rl>
/</rl>
tags
and copy them in the second XML file that looks almost the same but has no children elements between <rl>
/<rl>
.
The two files are in separate locations like:
c:/andrej/tmp1/file1.xml
c:/andrej/tmp2/file2.xml
What I learned from other posts is how to loop trough XML lines, but not how to copy and then somehow echo it or paste it to another XML file...
The code I have for now is:
(for /F "delims=" %%a in ("c:\andrej\tmp1\file1.xml") do (
set "line=%%a"
set "newLine=!line:roulettes>=!"
if "!newLine!" eq "!line!" (
rem ...
)
))
Can anyone help me?
Upvotes: 0
Views: 1817
Reputation: 24486
note: Your XML snippets aren't fully valid, by the way. The closer of your <b>
tag at the bottom of all your XML examples is missing a slash. This solution assumes you fixed that.
As others have pointed out, it's better to parse and objectify XML and other such structured markup than to hack and scrape it as flat text. The batch language unfortunately doesn't offer much for parsing XML, but it's easy enough to borrow from other languages.
PowerShell is particularly well-suited to handle XML. You can read an XML file as text, then cast that data as an XML object simply by prefacing it with [XML]
. Handy, right? From there, select the source node from XML1 and the destination node from XML2 using XPath expressions, then import from 1 into 2.
Here's a hybrid Batch + PowerShell script demonstrating this. Save this with a .bat extension and salt to taste.
<# : batch portion (begin multiline PowerShell comment)
@echo off & setlocal
set "xml1=c:\andrej\tmp1\file1.xml"
set "xml2=c:\andrej\tmp2\file2.xml"
if not exist "%xml1%" (
echo XML1: %xml1% not found.
exit /b 1
)
if not exist "%xml2%" (
echo XML2: %xml2% not found.
exit /b 1
)
rem // relaunch self with PowerShell
powershell -noprofile "iex (${%~f0} | out-string)"
rem // end of script
goto :EOF
: end batch / begin PowerShell hybrid code #>
$src = [xml](gc $env:xml1)
$dest = [xml](gc $env:xml2)
$src.SelectNodes("//roul/rl/*") | %{
"copying {0} and its descendents" -f $_.Name
[void]$dest.SelectSingleNode("//roul/rl").AppendChild($dest.ImportNode($_, $true))
}
$dest.Save($env:xml2)
write-host "Saved changes to ${env:xml2}" -f green
# // return execution back to Batch
Upvotes: 4