【问题标题】:Split a XML into multiple XMLs将一个 XML 拆分为多个 XML
【发布时间】:2017-12-12 17:43:12
【问题描述】:

我正在寻找可以将带有多个标签的大型 XML 拆分为多个 XML 文件的批处理/VBScript。请参阅下面的详细信息。


输入 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>

我下面的代码由于某种原因无法正常工作。谁能帮我讲逻辑? 我最初试图通过只有一个 &lt;shipment&gt; 标签的输入来获取数据。

代码:

    ::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

【问题讨论】:

  • 您正在寻找为您编写此代码的人。当你在 Stack Overflow 上提问时,你需要展示你在解决问题上所付出的努力。
  • 感谢您的免费建议,我是脚本新手,因此要求提供有问题的逻辑而不是完全代码
  • 您的代码不起作用,因为您有一个不匹配的右括号。另外,“大”到底有多大?

标签: xml batch-file vbscript


【解决方案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 文件可以以 gigs 为单位进行衡量,那么您可能别无选择。

【讨论】:

    【解决方案2】:

    使用 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(即兄弟节点有共同的单个根节点)。

    【讨论】:

      猜你喜欢
      • 2011-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多