我有一个Powershell脚本,该脚本返回的输出接近我想要的输出,但是我需要删除一些行和HTML样式的标签。我已经有以下代码可以过滤掉:
get-content "atxtfile.txt" | select-string -Pattern '<fields>' -Context 1
但是,如果我尝试将该输出传递给Second "select-string"
,则不会得到任何结果。我在网上查看REGEX示例,但是我所看到的大部分内容都涉及使用编码循环来实现其目标。我更习惯于Linux shell,在Linux shell中,您可以通过管道将输出分成多个greps
来过滤文本。有没有办法用PowerShell实现相同或相似的事情?这是我根据要求使用的文件:
<?xml version="1.0" encoding="UTF-8"?>
<CustomObject xmlns="http://soap.force.com/2006/04/metadata">
<actionOverrides>
<actionName>Accept</actionName>
<type>Default</type>
</actionOverrides>
<actionOverrides>
<actionName>CancelEdit</actionName>
<type>Default</type>
</actionOverrides>
<actionOverrides>
<actionName>Today</actionName>
<type>Default</type>
</actionOverrides>
<actionOverrides>
<actionName>View</actionName>
<type>Default</type>
</actionOverrides>
<compactLayoutAssignment>SYSTEM</compactLayoutAssignment>
<enableFeeds>false</enableFeeds>
<fields>
<fullName>ActivityDate</fullName>
</fields>
<fields>
<fullName>ActivityDateTime</fullName>
</fields>
<fields>
<fullName>Guid</fullName>
</fields>
<fields>
<fullName>Description</fullName>
</fields>
</CustomObject>
所以,我只想要<fullName>
描述符之间的文本,到目前为止我有以下内容:
get-content "txtfile.txt" | select-string -Pattern '<fields>' -Context 1
这将为我提供<fields>
描述符之间的所有内容,但是我基本上需要<fullName>
没有XML标记的行。
最简单的PSv3 +解决方案是使用PowerShell的内置XML DOM支持,该支持使XML文档的节点可以作为带有点标记的对象层次结构来访问:
PS> ([xml] (Get-Content -Raw txtfile.txt)).CustomObject.fields.fullName
ActivityDate
ActivityDateTime
Guid
Description
注意如何即使.fields
是一个阵列 -表示所有子<fields>
顶级元素的元素<CustomObject>
- .fullName
直接施加到其上和返回子元素的值<fullName>
在所有的数组元素(<field>
元素)作为阵列。
这种访问集合上属性并将其隐式应用于集合元素的功能(将结果收集到数组中)是一种通用的PSv3 +功能,称为成员枚举。
作为一个替代方案,可以考虑使用Select-Xml
小命令,这(在PSV2太可用)支持的XPath查询通常允许更复杂的提取逻辑(虽然不严格这里不需要); Select-Xml
是[xml]
.NET类型.SelectNodes()
方法的高级包装。
以下与上述解决方案等效:
$namespaces = @{ ns="http://soap.force.com/2006/04/metadata" }
$xpathQuery = '/ns:CustomObject/ns:fields/ns:fullName'
(Select-Xml -LiteralPath txtfile.txt $xpathQuery -Namespace $namespaces).Node.InnerText
注意:
与点符号不同,使用时必须考虑XML名称空间Select-Xml
。
鉴于其<CustomObject>
所有后代都在xmlns
通过URI标识的命名空间中http://soap.force.com/2006/04/metadata
,您必须:
-Namespace
xmlns
是特殊的,因为它不能用作哈希表中的键;而是选择一个任意的键名,例如ns
,但是请确保使用所选的键名作为节点名前缀(请参阅下一点)。:
;例如,ns:CustomObject