我有90mb的xml文件,我想在Linux Mac上处理&窗户他们有数百种"标签"像这样的节点:
<net.rptools.maptool.model.Label> ...few children... </net.rptools.maptool.model.Label>
我想处理文件以删除所有这些Label节点。然而,最好是把他们的父母,这似乎是一些
<labels class="linked-hash-map"> ...many megs of Label children... </labels>
我不知道哪个更好,直到我尝试将xml加载回应用程序。
我见过一些powershell XML处理的例子,它们似乎使用了Windows特定的api。从大型文件中删除节点时,首选的与平台无关的API和样式是什么?
如果您不想要任何花哨的api,只是将xml作为对象进行普通访问,那么只需将xml转换为[xml]对象即可
$xmldoc = [xml](Get-Content 'c:tempbooks.xml' -Raw)
或
$xmldoc = [xml]@"
<?xml version="1.0"?>
<catalog>
<book id="bk101">
<author>Gambardella, Matthew</author>
<title>XML Developer's Guide</title>
<genre>Computer</genre>
<price>44.95</price>
<publish_date>2000-10-01</publish_date>
<description>An in-depth look at creating applications
with XML.</description>
</book>
<book id="bk102">
<author>Ralls, Kim</author>
<title>Midnight Rain</title>
<genre>Fantasy</genre>
<price>5.95</price>
<publish_date>2000-12-16</publish_date>
<description>A former architect battles corporate zombies,
an evil sorceress, and her own childhood to become queen
of the world.</description>
</book>
</catalog>
"@
然后你可以通过它的属性
访问或修改xmlPS C:temp> $xmldoc.catalog.book
id : bk101
author : Gambardella, Matthew
title : XML Developer's Guide
genre : Computer
price : 44.95
publish_date : 2000-10-01
description : An in-depth look at creating applications
with XML.
id : bk102
author : Ralls, Kim
title : Midnight Rain
genre : Fantasy
price : 5.95
publish_date : 2000-12-16
description : A former architect battles corporate zombies,
an evil sorceress, and her own childhood to become queen
of the world.
如果你修改了,你可以使用
将修改过的对象写回文件$xmldoc.Save("C:temptestout.xml")
我选择了下面的例子。应用程序不允许我删除"标签"。net.rptools.maptool.model.Label"节点是"entry"的子节点。节点。因此,我使用带有XPath表达式的SelectNodes
来查找所有"条目"。"标签"下的节点父目录,然后从父目录中删除它们:
#!/usr/bin/env pwsh
Set-StrictMode -Version Latest
$branch = Get-Location
$contentFileIn = "$branchcontent.xml"
$contentFileOut = "$branchcontent_pruned.xml"
$xmlDoc = [xml]::new()
$xmlDoc.Load($contentFileIn)
$entryNodes = $xmlDoc.SelectNodes("//labels/entry")
foreach ($entryNode in $entryNodes){
$entryNode.ParentNode.RemoveChild($entryNode)
}
$xmldoc.Save($contentFileOut)
使用XSLT很容易删除具有给定名称的元素,XSLT几乎是与平台无关的。在XSLT 3.0中,它很简单:
<xsl:transform version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="label"/>
</xsl:transform>
XSLT 1.0更广泛使用,但稍微冗长一些:
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="*">
<xsl:copy><xsl:apply-templates/></xsl:copy>
</xsl:template>
<xsl:template match="label"/>
</xsl:transform>
通过解释,在这两种情况下,您都在说默认情况下,元素被递归地浅复制到结果,除了标签元素,它不生成输出(即它们被删除)。