如何使用PowerShell创建xml文件的子集或过滤掉xml文件的子节点?

时间:2015-04-28 17:11:43

标签: xml powershell xslt

我有一个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变换的内容,但也不熟悉。

感谢您的帮助。

2 个答案:

答案 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 ..

enter image description here