Question

I'm working on a deployment solution for SQL Server Analysis Services with Jenkins and RedGate DeploymentManager2.

I have this bit of code which executes an XMLA file on the given server: (Please note, that this snipet is simplified, I have more error checks in the real solution, but this is enough to understand my problem)

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"

Here is an example error output (generated by providing a non-existent database name for the Process command):

  <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>

My goal is to check this output for errors.

This is my current code to achieve this (and works fine - also simplified for better understanding):

# 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

As I mentioned, this works fine, but...

When I tried to process the above XML file, I tried it without using namespaces like this:

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

Write-Host $exceptionNodes.Count # Output: 0

With using the object-like access:

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

It can find the node with and without using namespaces.

Output for the above code:

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

Why PowerShell is so inconsistent when it works with XML with namespaces?

-- OR --

What did I wrong, when I tried to work with the given example XML without using namespaces?

Any information is appreciated!

More info about error handling while running XMLA: Handling Errors and Warnings (XMLA)

Environment

  • Windows 7 64bit
  • Powershell 2.0
  • SQL Server 2012 (+ AS)
Was it helpful?

Solution

The XPath expression //Exception will only match elements that are in no namespace. So returning no elements at all is expected there. You can work around that by using //*[local-name()='Exception' (syntax might be slightly off, but you get the idea).

The reason because accessing the properties works is because PowerShell helpfully creates those properties without regard for namespaces. This is helpful when dealing interactively with XML files. But it breaks down when you mix namespaces and have the same element with different namespaces – you couldn't distinguish them.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top