PowerShell处理XML(二)加载和处理XML文件 4


PowerShell处理XML系列文章

  1. XML 结构
  2. 加载和处理XML文件
  3. 浏览扩展类型系统

如果你想将XML文件按照实际的XML来处理,而不是纯文本。文件的内容必须转换成XML类型。类型转换在第六章已经提到,只须一行。

$xmldata = [xml](Get-Content employee.xml)

Get-Content从之前保存的xml文件中读取xml内容,然后使用[xml]将xml内容转换成真正的XML。你可以将xml文本直接转换成XML,然后保存在变量$xml中:

$xmldata = [xml]$xml

然而,转换只会在指定的xml文本合法并不包含解析错误时有效。当你尝试转换的xml文件结构不合法,会报错。

用来描述XML的结构和信息现在被存放在变量$xmldata。从现在开始,获取一小段信息将会变得非常容易,因为XML对象将每个结点转换成了属性。你可以像这样获取员工信息:

$xmldata.staff.employee
Name		Function	Age
----		-----		-----
Tobias	Weltner	management	39
Cofi Heidecke	security	4

访问和更新单个结点

如果一个结点在xml中是唯一的,你可以像前面的例子一样输入一个句号来访问它。然而,多数情况下XML文档包含了许多类似的结点(被称为兄弟结点),像前面最后一个例子中一样,包含了多个独立的员工。比如,你可以使用管道获得特定的员工,然后来更新它的数据。

$xmldata.staff.employee |
Where-Object { $_.Name -match "Tobias Weltner" }
Name           function   age
----           --------   ---
Tobias Weltner management 39
$employee = $xmldata.staff.employee |
Where-Object { $_.Name -match "Tobias Weltner" }
$employee.function = "vacation"
$xmldata.staff.employee | ft -autosize
Name           function age
----           -------- ---
Tobias Weltner vacation 39
Cofi Heidecke  security 4

使用SelectNodes()来选择Nodes

SelectNodes()方法是Xpath查询语言支持的方法,也允许你选择结点。XPath指的是一个结点‘路径名称’:

$xmldata = [xml](Get-Content employee.xml)
$xmldata.SelectNodes("staff/employee")
Name           function   age
----           --------   ---
Tobias Weltner management 39
Cofi Heidecke  security   4

结果看起来像前面直接通过属性访问一样,但是XPath支持在方括号中使用通配符访问。下面的语句只会返回第一个员工结点。

PS> $xmldata.SelectNodes("staff/employee[1]") 

Name           function   age
----           --------   ---
Tobias Weltner management 39

如果你想,你还可以获取一个年龄小于18岁的员工列表:

PS> $xmldata.SelectNodes("staff/employee[age<18]")

Name          function age
----          -------- ---
Cofi Heidecke security 4

类似的方式,查询语言也支持获取列表中的最后一位员工信息,所以也可以指定位置:

$xmldata.SelectNodes("staff/employee[last()]")
$xmldata.SelectNodes("staff/employee[position()>1]")

或者,你可以使用所谓的XpathNavigator,从中获取许多从XML文本的类型转换。

# 创建一个 XML定位:
$xpath = [System.XML.XPath.XPathDocument]`
[System.IO.TextReader][System.IO.StringReader]`
(Get-Content employee.xml | out-string)
$navigator = $xpath.CreateNavigator()

# 输出Hanover子公司的最后一位员工
$query = "/staff[@branch='Hanover']/employee[last()]/Name"
$navigator.Select($query) | Format-Table Value

Value
-----
Cofi Heidecke

# 输出Hanover子公司的除了Tobias Weltner之外的所有员工,
$query = "/staff[@branch='Hanover']/employee[Name!='Tobias
Weltner']"
$navigator.Select($query) | Format-Table Value

Value
-----
Cofi Heideckesecurity 4

荔非苔注:如果你的XML文档包含命名空间,SelectNodes时稍有不同,可以参考这篇文章PowerShell 基于Namespace来SelectNode

访问属性

属性是定义在一个XML标签中的信息,如果你想查看结点的属性,可以使用get_Attributes()方法:

$xmldata.staff.get_Attributes()
#text
-----
Hanover
sales

使用GetAttribute()方法来查询一个特定的属性:

$xmldata.staff.GetAttribute("branch")
Hanover

使用SetAttribute()方法来指定新的属性,或者更新(重写)已有的属性。

$xmldata.staff.SetAttribute("branch", "New York")
$xmldata.staff.GetAttribute("branch")
New York

添加新结点

如果你想在员工结点列表中添加新的员工。首先,使用CreateElement()创建一个员工元素,然后定制员工的内部结构。最后,就可以在XML结构中你期望的位置插入这个元素。

# 加载XML文本文件:
$xmldata = [xml](Get-Content employee.xml)
# 创建新的结点:
$newemployee = $xmldata.CreateElement("employee")
$newemployee.set_InnerXML( `
"<Name>Bernd Seiler</Name><function>expert</function>")
# 插入新结点:
$xmldata.staff.AppendChild($newemployee)
# 验证结果:
$xmldata.staff.employee
Name           function   age
----           --------   ---
Tobias Weltner management 39
Cofi Heidecke  security   4
Bernd Seiler   expert
# 输出为纯文本:
$xmldata.get_InnerXml()
<?xml version="1.0"?><Branch office staff="Hanover" Type="sales">
<employee><Name>Tobias Weltner</Name><function>management</function>
<age>39</age></employee><employee><Name>Cofi Heidecke</Name>
<function>security</function><age>4</age></employee><employee>
<Name>Bernd Seiler</Name><function>expert</function></employee></staff>

保存XML文件

$xmldata.Save(“$env:temp\updateddata.xml”)

原文链接:Chapter 14. XML

本文链接: https://www.pstips.net/loading-and-processing-xml-files.html
请尊重原作者和编辑的辛勤劳动,欢迎转载,并注明出处!

关于 Mooser Lee

我是一个Powershell的爱好者,创建了PowerShell中文博客,热衷于Powershell技术的搜集和分享。本站部分内容来源于互联网,不足之处敬请谅解,并欢迎您批评指正。

发表评论

您的电子邮箱地址不会被公开。 必填项已用 * 标注

4 条评论 “PowerShell处理XML(二)加载和处理XML文件