我有下面的xml文件,有id和值。需要field_name =test2的结果,id为3
<Types>
<Type field_name="Test1">
<items>
<item>
<id>1</id>
<value>A</value>
</item>
<item>
<id>2</id>
<value>B</value>
</item>
<item>
<id>3</id>
<value>C</value>
</item>
<item>
<id>4</id>
<value>D</value>
</item>
</items>
</Type>
<Type field_name="Test2">
<items>
<item>
<id>1</id>
<value>A</value>
</item>
<item>
<id>2</id>
<value>B</value>
</item>
<item>
<id>3</id>
<value>C</value>
</item>
<item>
<id>4</id>
<value>D</value>
</item>
</items>
</Type>
</Types>
我需要通过field_name =test2获得id的结果,我尝试了下面的代码,但没有成功。
$xml = [xml](Get-Content "C:\Test.xml")
$xml.types.type.items.item | ? {$_.id -eq 3} | select value
1条答案
按热度按时间yftpprvb1#
请注意,PSv4 +
.Where()
和.ForEach()
数组方法用于过滤和枚举,特别是需要使用.ForEach()
显式枚举<item>
子元素(参见下节)。注意:严格地说,由于
.Where()
调用只返回一个 * single * 对象,该对象只有一个 * single *items
子元素,因此.ForEach()
在 * this * 情况下并不是严格必需的,但在原始代码中却是必需的。另请注意
@(...)
的使用,这仅在 * Windows PowerShell * 中是必需的,因为 * PowerShell(Core)7 +* 中已修复了一个错误但是,使用XPath查询更容易,它与
Select-Xml
结合使用,可实现单命令解决方案:注:
-Namespace
参数,并在查询中引用元素时使用这些前缀-有关详细信息,请参见this answer。至于你所尝试的:
除了您的代码没有尝试按
field_name="Test2"
进行过滤(如果id
值在整个文档中是唯一的,则可能不需要)之外,您的问题还在于对值为 * array * 的父属性.items
使用了.item
属性:.items
是一个 * 数组 ,并且数组有一个 * type-native *.Item
成员*[1],所以该成员优先于PowerShell's adaptation of the XML DOM(其中属性和子元素看起来 * 就像 * 它们是属性一样),所以**名为item
的XML子元素不再可以通过.item
**直接访问。.ForEach({ $_.item })
[2]显式枚举数组元素(在本例中是XML元素)可以绕过这个问题**,然后访问每个[XmlElement]
上的.item
属性就可以正常工作。注意:
XmlElements
也有一个类型原生的.Item
属性,但在PowerShell对XML DOM的适应上下文中,逻辑是 * 相反的 : adapted * 属性优先于类型原生属性(后者可以作为带有get_
前缀的 * methods * 访问;例如,.get_Index()
)-参见this answer,以获得一个修改后的.Name
属性(来自子元素或属性)隐藏元素的类型原生属性的示例。[1]从技术上讲,参数化的
.Item
属性是通过 * interface *(IList
)公开的,但PowerShell将此类显式接口实现属性作为类型的直接属性公开。[2]理想情况下,您可以使用
.ForEach('item')
作为更快的替代方案,但截至PowerShell(核心)7.2,由于GitHub issue #15994中详细介绍的一个 * bug *,这不起作用。