xml - 如何使用 PowerShell 从此 XML 中提取 ErrorCode 和 ErrorDescription?
问题描述
我在尝试从以下 XML 中获取 ErrorCode 和 ErrorDescription 的值时遇到了很多困难:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<ActionResponse xmlns="http://tempuri.org/">
<ActionResult xmlns:a="http://schemas.datacontract.org/2004/07/RL.Common.CommonTypes" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:ErrorCode>1</a:ErrorCode>
<a:ErrorDescription>General Error</a:ErrorDescription>
</ActionResult>
</ActionResponse>
</s:Body>
</s:Envelope>
尝试了以下方法,它正在工作,但在我看来,这种工作方式很糟糕:
cls
$res = [xml]@'
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<ActionResponse xmlns="http://tempuri.org/">
<ActionResult xmlns:a="http://schemas.datacontract.org/2004/07/RL.Common.CommonTypes" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:ErrorCode>1</a:ErrorCode>
<a:ErrorDescription>General Error</a:ErrorDescription>
</ActionResult>
</ActionResponse>
</s:Body>
</s:Envelope>
'@
$XPath = "/ns:Envelope/ns:Body"
[xml]$xml = $res
$namespace = $xml.DocumentElement.NamespaceURI
$ns = New-Object System.Xml.XmlNamespaceManager($xml.NameTable)
$ns.AddNamespace("ns", $namespace)
$ns.AddNamespace("nsa", "http://tempuri.org/")
$ns.AddNamespace("nsb", "http://tempuri.org/")
$product = $xml.SelectSingleNode($XPath, $ns)
Write-Host $product
#exit
$XPath = "/ns:Envelope/ns:Body"
[xml]$xml = $res
$namespace = $xml.DocumentElement.NamespaceURI
$ns = New-Object System.Xml.XmlNamespaceManager($xml.NameTable)
$ns.AddNamespace("ns", $namespace)
$product = $xml.SelectSingleNode($XPath, $ns)
#Write-Host $product.InnerXml
#$newres = [xml]@'
#<ActionResponse xmlns="http://tempuri.org/"><ActionResult xmlns:a="http://schemas.datacontract.org/2004/07/RL.Common.CommonTypes" xmlns:i="http://www.w3.org/2001/XMLS
#chema-instance"><a:ErrorCode>1</a:ErrorCode><a:ErrorDescription>General Error</a:ErrorDescription></ActionResult></ActionResponse>
#'@
[xml]$newres = $product.InnerXml
$XPath = "/ns:ActionResponse"
[xml]$xml = $newres
$namespace = $xml.DocumentElement.NamespaceURI
$ns = New-Object System.Xml.XmlNamespaceManager($xml.NameTable)
$ns.AddNamespace("ns", $namespace)
$product = $xml.SelectSingleNode($XPath, $ns)
$XPath = "/ns:ActionResult"
[xml]$xml = $product.InnerXml
$namespace = $xml.DocumentElement.NamespaceURI
$ns = New-Object System.Xml.XmlNamespaceManager($xml.NameTable)
$ns.AddNamespace("ns", $namespace)
$product = $xml.SelectSingleNode($XPath, $ns)
Write-Host "ErrCode: ",$product.ErrorCode ," ErrDesc: ",$product.ErrorDescription
Write-Host $product.ErrorCode, $product.ErrorDescription
我想难以获得值的原因是由于这里使用的名称空间(几个)提前感谢所有帮助。
解决方案
如果您不关心命名空间或使用 XPATH,您可以使用Frenchy's Answer 。
如果您不关心命名空间但必须使用 XPATH,您可以使用该local-name()
功能。
$res = [xml]@'
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<ActionResponse xmlns="http://tempuri.org/">
<ActionResult xmlns:a="http://schemas.datacontract.org/2004/07/RL.Common.CommonTypes" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:ErrorCode>1</a:ErrorCode>
<a:ErrorDescription>General Error</a:ErrorDescription>
</ActionResult>
</ActionResponse>
</s:Body>
</s:Envelope>
'@
$XPath = '//*[local-name() = "ErrorCode" or local-name() = "ErrorDescription"]'
$Nodes = (Select-Xml -Xml $res -XPath $XPath).Node
$Nodes # Your Xml elements
如果要使用定义的命名空间和 XPATH,可以执行以下操作:
$res = [xml]@'
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<ActionResponse xmlns="http://tempuri.org/">
<ActionResult xmlns:a="http://schemas.datacontract.org/2004/07/RL.Common.CommonTypes" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:ErrorCode>1</a:ErrorCode>
<a:ErrorDescription>General Error</a:ErrorDescription>
</ActionResult>
</ActionResponse>
</s:Body>
</s:Envelope>
'@
$XPath = '/s:Envelope/s:Body/NSWithNoName:ActionResponse/NSWithNoName:ActionResult/a:*["ErrorCode" or "ErrorDescription"]'
$ns = @{ a = 'http://schemas.datacontract.org/2004/07/RL.Common.CommonTypes'
s = "http://schemas.xmlsoap.org/soap/envelope/"
NSWithNoName = "http://tempuri.org/"
}
$Nodes = (Select-Xml -Xml $res -XPath $XPath -Namespace $ns).Node
$Nodes # Your xml elements ErrorCode and ErrorDescription
在这里,您有一个没有指定名称的命名空间定义。由于我们使用哈希表来管理命名空间,因此最好在该哈希表中给它一个名称/键。然后,您可以在 XPATH 表达式中引用哈希表键名。
您可以修改 XPATH 以改为选择ActionResult
节点。然后使用另一个Select-Xml
具有不同 XPATH 的来选择ErrorCode
和ErrorDescription
节点。
$XPath = '/s:Envelope/s:Body/NSWithNoName:ActionResponse/NSWithNoName:ActionResult'
$ARNode = (Select-Xml -Xml $res -XPath $XPath -Namespace $ns).Node
$ECNode = (Select-Xml -Xml $ARNode -XPath './a:ErrorCode' -Namespace $ns).Node
$EDNode = (Select-Xml -Xml $ARNode -XPath './a:ErrorDescription' -Namespace $ns).Node
推荐阅读
- vue.js - 每次导航发生时都会执行 nuxtServerInit
- python - 使用关键字参数模拟方法
- jquery - 使用路线服务时,我在属性“目的地”中收到 InvalidValueError
- r - ggplot 返回一个堆叠的条形图而不是一个单独的条形图
- codeigniter - 如何在codeigniter 4中自动加载自制的配置文件?
- javascript - ExtJS:从 Ajax 发布请求响应中获取文件
- android - MediaRecorder.start() 有时会抛出 java.lang.RuntimeException: start failed
- sql - 如何使用行值 sqlite 更新列
- angularjs - Angular 混合应用程序 - Angular 2 路由器不工作
- php - WordPress:使用帖子 ID 和帖子标题作为上传图片的文件名