澄清PowerShell的XML解析器的不一致(?)行为

时间:2014-05-13 07:26:03

标签: xml powershell ssas

我正在使用Jenkins和RedGate DeploymentManager2开发SQL Server Analysis Services的部署解决方案。

我有一些代码在给定服务器上执行XMLA文件: (请注意,这个snipet已经简化了,我在真正的解决方案中有更多的错误检查,但这足以理解我的问题)

Import-Module SQLPS
Import-Module sqlascmdlets

[string]$xmlaPath = "D:\Test\process.xmla";
[string]$asServer = "MyServer"
[string]$asCmdResultPath = "D:\Test\test.xml"
[string]$asCmdTracePath = "D:\Test\test.astrace"

Invoke-ASCmd -InputFile "$xmlaPath" -Server "$asServer" -TraceFile "$asCmdTracePath" -ErrorAction Stop | Out-File "$asCmdResultPath"

以下是一个示例错误输出(通过为Process命令提供不存在的数据库名称生成):

  <return xmlns="urn:schemas-microsoft-com:xml-analysis">
      <root xmlns="urn:schemas-microsoft-com:xml-analysis:empty">
         <Exception xmlns="urn:schemas-microsoft-com:xml-analysis:exception" />
         <Messages xmlns="urn:schemas-microsoft-com:xml-analysis:exception">
            <Warning WarningCode="-1055653884" Description="Errors in the metadata manager. ... bla.. bla.. bla.." Source="Microsoft SQL Server 2012 Analysis Services" HelpFile="" />
         </Messages>
      </root>
   </return>

我的目标是检查此输出是否有错误。

这是我目前实现此目的的代码(并且工作正常 - 也为了更好地理解而简化):

# Processing result XML generated by Invoke-ASCmd
[xml]$resultXml = [xml](Get-Content $asCmdResultPath)

[System.Xml.XmlNamespaceManager]$nsmgr = $resultXml.NameTable

$nsmgr.AddNamespace($null, 'urn:schemas-microsoft-com:xml-analysis')
$nsmgr.AddNamespace('ase', 'urn:schemas-microsoft-com:xml-analysis:empty')
$nsmgr.AddNamespace('asex', 'urn:schemas-microsoft-com:xml-analysis:exception')
$nsmgr.AddNamespace('soap', 'http://schemas.xmlsoap.org/soap/envelope/')

$exceptionNodes = $resultXml.SelectNodes("//asex:Exception", $nsmgr)

Write-Host $exceptionNodes.Count # Output: 1

正如我所提到的,这很好,但是......

当我尝试处理上述XML文件时,我尝试了它而不使用这样的命名空间:

[xml]$resultXml = [xml](Get-Content $asCmdResultPath)
$exceptionNodes = $resultXml.SelectNodes("//Exception")

Write-Host $exceptionNodes.Count # Output: 0

使用类似对象的访问:

$x = $resultXml."return".root.Exception
Write-Host "Object: $($x | Format-Table | Out-String)"

它可以在使用和不使用命名空间的情况下找到节点。

上述代码的输出:

xmlns
-----
urn:schemas-microsoft-com:xml-analysis:exception

为什么PowerShell在使用带名称空间的XML时会如此不一致?

- 或 -

当我尝试使用给定的示例XML而不使用命名空间时,我错了什么?

感谢任何信息!

有关运行XMLA时错误处理的详细信息:Handling Errors and Warnings (XMLA)

环境

  • Windows 7 64位
  • Powershell 2.0
  • SQL Server 2012(+ AS)

1 个答案:

答案 0 :(得分:1)

XPath表达式//Exception只匹配没有名称空间的元素。因此,预计不会返回任何元素。你可以使用//*[local-name()='Exception'解决这个问题(语法可能略有偏差,但你明白了。)

因为访问属性的原因是因为PowerShell有助于创建这些属性而不考虑名称空间。在交互式处理XML文件时,这很有用。但是当你混合命名空间并且具有不同命名空间的相同元素时它就会崩溃 - 你无法区分它们。