这是一个替代解决方案,不使用 xpath,而是使用字符串替换和正则表达式。效率高,可以写成一行(看最后一行)。
我的文件如下:
<?xml version="1.0" encoding="utf-8"?>
<body>
<node1 attribute1="attr1">
<child1 attribute1="A">
<grandchild>
</grandchild>
</child1>
<child2 attribute1="B">
<grandchild>
</grandchild>
</child2>
</node1>
<node2 attribute1="attr1">
<child1 attribute1="A">
<grandchild>
</grandchild>
</child1>
<child2 attribute1="B">
<grandchild>
</grandchild>
</child2>
</node2>
</body>
我首先使用 Get-Content 的 -raw 参数将其作为单个字符串加载到 var ($a) 中。
$a =Get-Content 'D:\temp\M4.xml' -raw
然后我用一个正则表达式来替换你不想要的节点。
$a -replace '(?sm) <child1.*?Child1>\r\n','' | set-content 'd:\temp\filewithoutchild1.xml'
结果是:
<?xml version="1.0" encoding="utf-8"?>
<body>
<node1 attribute1="attr1">
<child2 attribute1="B">
<grandchild>
</grandchild>
</child2>
</node1>
<node2 attribute1="attr1">
<child2 attribute1="B">
<grandchild>
</grandchild>
</child2>
</node2>
</body>
正则表达式的诀窍是使用 (?sm) 你会发现一个很好的解释here。
使用一行:
(Get-Content 'D:\temp\M4.xml' -raw) -replace '(?sm) <child1.*?Child1>\r\n','' | set-content 'd:\temp\filewithoutchild1.xml'
于 2015 年 5 月 5 日编辑
所以现在工作文件看起来像:
<?xml version="1.0" encoding="utf-8"?>
<body>
<node1 attribute1="attr1">
<child1 attribute1="A">
<grandchild>
</grandchild>
</child1>
<child1 attribute1="B">
<grandchild>
</grandchild>
</child1>
<child1 attribute1="C">
<grandchild>
</grandchild>
</child1>
</node1>
<node2 attribute1="attr1">
<child1 attribute1="A">
<grandchild>
</grandchild>
</child1>
<child1 attribute1="B">
<grandchild>
</grandchild>
</child1>
<child1 attribute1="C">
<grandchild>
</grandchild>
</child1>
</node2>
</body>
这是允许您仅选择所需子节点的代码。虽然它在技术上有效,但我并不为此感到骄傲。
我使用相同的方式,但这次我循环删除标签,而它只存在您需要的标签。在示例中,我保留“C”国家代码。
Clear-Host
$a =Get-Content 'D:\temp\M.xml' -raw
$reg = [regex]'(?sm)( <child1.*?</child1>)'
$tagMatches = $reg.Matches($a)
$blRemoved = $true
while ($blRemoved)
{
$tagMatches = $reg.Matches($a)
$blRemoved = $false
foreach ($tagMatch in $tagMatches)
{
if ($tagMatch.value -notlike "*`"C`"*")
{
Write-Host $tagMatch.value
$a = $a.Remove($tagMatch.Index,$tagMatch.Length+4)
$blRemoved = $true
break
}
}
}
$a