我有一个xml文件,如下所示
...
<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>
我想使用powershell创建另一个xml文件,只包含所有child1节点或所有child2节点。
我也读过有关xslt变换的内容,但也不熟悉。
感谢您的帮助。
答案 0 :(得分:1)
这是一个替代解决方案,不使用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>
我首先使用$a
的{{1}}参数将var(-raw
)作为单个字符串加载。
Get-Content
然后我使用正则表达式替换你不想要的节点。
$a =Get-Content 'D:\temp\M4.xml' -raw
结果是:
$a -replace '(?sm) <child1.*?Child1>\r\n','' | set-content 'd:\temp\filewithoutchild1.xml'
正则表达式中的技巧是(?sm)你会找到一个很好的解释here。
使用一行:
<?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>
于05/05/2015编辑
现在工作文件看起来像:
(Get-Content 'D:\temp\M4.xml' -raw) -replace '(?sm) <child1.*?Child1>\r\n','' | set-content 'd:\temp\filewithoutchild1.xml'
以下是允许您仅选择所需子节点的代码。虽然技术起作用,但我并不为此感到骄傲。
我使用相同的方式,但这次我循环删除标签,而它只存在你需要的标签。在示例中,我保持&#34; C&#34;国家代码。
<?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>
答案 1 :(得分:0)
PowerShell有一个名为Select-XML
的内置Cmdlet,非常适合此任务。假设您已将此XML文件存储在名为。\ SomeFile.xml的文件中,并希望获得所有名为&#39; Child1&#39;
$xml = [xml](gc T:\SomeFile.xml)
$xml | Select-Xml -XPath //child1
Node Path Pattern
---- ---- -------
child1 InputStream //child1
child1 InputStream //child1
您使用XPath的&#39; //&#39; to say&#39;给我所有以此为结尾的节点。抓住孩子们。如果你想做一些更复杂的事情,你需要查看一些XPath参考。
这是一本快速参考指南。请务必查看'Selecting Nodes' here,了解更多XPath Goodness ..