将XML拆分为多个XML

时间:2017-07-08 14:58:35

标签: xml batch-file vbscript

我正在寻找一个批处理/ VBScript,它可以将带有多个标记的大型XML拆分成多个XML文件。请看下面的详细信息。

输入XML:

<Shipment>
----some data- say 001-------
</Shipment>
< Shipment>
---- Some data- say 002-------
</Shipment>

****输出XML 1:****

<Shipment>
---some data- say 001-------
</Shipment>

输出XML 2:

<Shipment>
----some data- say 002-------
</Shipment>

我的代码因某些原因无效。任何人都可以帮我逻辑吗? 我正在尝试使用只有<shipment>个标记的输入来获取数据。

代码:

    ::Read Xml file
    set f_xml=input2.xml    
    for %%i in (%f_xml%) do (
        set xmlfilename=%%~ni
    )

    ::Write XML file 
    for /f "tokens=1* delims=]" %%b in ('type "!xmlfilename!" ^| find /n /v ""') do (
        if /i *%%c*==*[Shipment]* set inblock=1
        if !inblock!==1 (
            if *%%c*==** (echo.) else (echo %%c)
            if /i *%%c*==*[/Shipment]* set inblock=0
        )
    )
    echo. 
) >> output.xml

2 个答案:

答案 0 :(得分:1)

最好解析和客观化XML和其他类似的结构化标记,而不是将其作为平面文本进行破解和删除。遗憾的是,cmd解释器本身不能解析XML,但是从其他脚本引擎借用它很容易。

PowerShell特别适合处理XML。您可以将XML文件作为文本读取,然后只需将其与[xml]加速器对齐,就可以将该数据转换为XML对象。好用,对吧?从那里,使用XPath表达式选择所有Shipment个节点;然后为每个克隆到一个新的XML对象并保存。

这是一个混合的Batch + PowerShell脚本,展示了这一点。使用.bat扩展名和盐来保存它。

<# : Batch portion
@echo off & setlocal

set "xmlfile=test.xml"

powershell -noprofile "iex (${%~f0} | out-string)"
goto :EOF

: end Batch / begin PowerShell hybrid code #>

[xml]$xml = "<root>$(gc $env:xmlfile)</root>"

$xml.SelectNodes("//Shipment") | %{
    $x = new-object xml
    $x.AppendChild($x.ImportNode($_, $true))
    $x.Save("shipment{0:D3}.xml" -f ++$i)
}

此方法的缺点是,即使保存第一个块,也必须将大型XML文件加载到内存中。根据“大”的大小,您可能不得不求助于流阅读器和平面文本抓取来加速执行(类似于您最初的预期,但使用比Batch for /f更高效的阅读器)。如果可能,应该避免使用平面文本抓取(参见this ugly example)。但是如果你正在使用可以在演出中测量的XML文件,那么你可能别无选择。

答案 1 :(得分:0)

使用VBScript将兄弟节点写入单个文件的一种非常基本的方法是将输入文件作为XML读取,并将各个节点的XML文本导出为纯文本:

Set xml = CreateObject("Msxml2.DOMDocument.6.0")
xml.Async = False
xml.Load "C:\path\to\input.xml"

If xml.ParseError <> 0 Then
    WScript.Echo xml.ParseError.Reason
    WScript.Quit 1
End If

i = 1
Set fso = CreateObject("Scripting.FileSystemObject")
For Each n In xml.SelectNodes("//Shipment")
    outfile = fso.BuildPath("C:\path\to", "output" & i & ".xml")
    Set f = fso.CreateTextFile(outfile)
    f.Write n.Xml
    f.Close
    i = i + 1
Next

请注意,此代码不会向输出文件添加XML声明。如果您需要,您需要自己添加。

另请注意,上述代码假定输入文件是有效的XML(即兄弟节点具有共同的单根节点)。